-
Notifications
You must be signed in to change notification settings - Fork 715
Description
Limiting asset access: restrict-assets?
Originally proposed here.
restrict-assets? establishes a context with a deny-all outflow policy for a
specific principal during the evaluation of its body expressions. It accepts a
set of allowances, defined using with-stx, with-ft, with-nft, and
with-stacking, which selectively grant outflow allowances. After the body
expressions finish, the Clarity VM checks the gross outflow from the scoped
principal against the granted allowances. If any allowance is exceeded,
restrict-assets? returns an error; otherwise, it returns ok with the result
of the last body expression.
The most important use case of these new builtins is to allow a contract to
protect its own assets. To ensure that the contract's assets are safe by
default, the new as-contract? expression is similar to the existing
as-contract expression, but will implicitly behave as though there is a
restrict-assets? expression around its body, specifying the contract principal
as the asset owner. The old as-contract is no longer available in Clarity 4.
Similar to restrict-assets?, as-contract? accepts a set of with-stx,
with-ft, with-nft, and with-stacking expressions which selectively grant
outflow allowances from the contract's assets.
with-stxgrants an outflow allowance for a specific amount of STX via calls
to thestx-transfer?function.with-ftgrants an outflow allowance for a specific amount of the specified
fungible token.with-nftgrants an outflow allowance for a specific identifier of the
specified NFT.with-stackinggrants an outflow allowance for a specific amount of STX via
calls to thestack-stxordelegate-stxfunctions of the active PoX
contract.
Use of with-stx, with-ft, with-nft, or with-stacking outside of
restrict-assets? or as-contract? results in an analysis error.
-
restrict-assets?-
Input:
asset-owner:principal: The principal whose assets are being
protected.((with-stx|with-ft|with-nft|with-stacking)*): The set of allowances to
grant during the evaluation of the body expressions.AnyType* A: The Clarity expressions to be executed within the context,
with the final expression returning typeA, whereAis not a
response
-
Output:
(response A int) -
Signature:
(restrict-assets? asset-owner ((with-stx|with-ft|with-nft|with-stacking)*) expr-body1 expr-body2 ... expr-body-last) -
Description: Executes the body expressions, then checks the asset
outflows against the granted allowances, in declaration order. If any
allowance is violated, the body expressions are reverted, an error is
returned, and an event is emitted with the full details of the violation to
help with debugging. Note that theasset-ownerand allowance setup
expressions are evaluated before executing the body expressions. The final
body expression cannot return aresponsevalue in order to avoid returning
a nestedresponsevalue from therestrict-assets?(nested responses are
error-prone). Returns:(ok x)if the outflows are within the allowances, wherexis the
result of thebodyexpression and has typeA.(err index)if an allowance was violated, whereindexis the 0-based
index of the first violated allowance in the list of granted allowances,
or -1 if an asset with no allowance caused the violation.
-
Example:
(define-public (foo) (restrict-assets? tx-sender () (try! (stx-transfer? u1000000 tx-sender 'ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM)) ) ) ;; Returns (err -1) (define-public (bar) (restrict-assets? tx-sender () (+ u1 u2) ) ) ;; Returns (ok u3)
-
-
with-stx- Input:
amount:uint: The amount of uSTX to grant access to.
- Output: Not applicable
- Signature:
(with-stx amount) - Description: Adds an outflow allowance for
amountuSTX from the
asset-ownerof the enclosingrestrict-assets?oras-contract?
expression. - Example:
(restrict-assets? tx-sender ((with-stx u1000000)) (try! (stx-transfer? u2000000 tx-sender 'ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM)) ) ;; Returns (err 0) (restrict-assets? tx-sender ((with-stx u1000000)) (try! (stx-transfer? u1000000 tx-sender 'ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM)) ) ;; Returns (ok true)
- Input:
-
with-ft- Input:
contract-id:principal: The contract defining the FT asset.token-name:(string-ascii 128): The name of the FT or"*"for any FT
defined incontract-id.amount:uint: The amount of FT to grant access to.
- Output: Not applicable
- Signature:
(with-ft contract-id token-name amount) - Description: Adds an outflow allowance for
amountof the fungible
token defined incontract-idwith nametoken-namefrom theasset-owner
of the enclosingrestrict-assets?oras-contract?expression. Note,
token-nameshould match the name used in thedefine-fungible-tokencall
in the contract. - Example:
(restrict-assets? tx-sender ((with-ft (contract-of token-trait) "stackaroo" u50)) (try! (contract-call? token-trait transfer u100 tx-sender 'ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM none)) ) ;; Returns (err 0) (restrict-assets? tx-sender ((with-ft (contract-of token-trait) "stackaroo" u50)) (try! (contract-call? token-trait transfer u20 tx-sender 'ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM none)) ) ;; Returns (ok true)
- Input:
-
with-nft- Input:
contract-id:principal: The contract defining the NFT asset.token-name:(string-ascii 128): The name of the NFT or"*"for any
NFT defined incontract-id.identifier:T: The identifier of the token to grant access to.
- Output: Not applicable
- Signature:
(with-nft contract-id token-name identifier) - Description: Adds an outflow allowance for the non-fungible token
identified byidentifierdefined incontract-idwith nametoken-name
from theasset-ownerof the enclosingrestrict-assets?oras-contract?
expression. Note,token-nameshould match the name used in the
define-non-fungible-tokencall in the contract. - Example:
(restrict-assets? tx-sender ((with-nft (contract-of nft-trait) "stackaroo" u123)) (try! (contract-call? nft-trait transfer u4 tx-sender 'ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM)) ) ;; Returns (err 0) (restrict-assets? tx-sender ((with-nft (contract-of nft-trait) "stackaroo" u123)) (try! (contract-call? nft-trait transfer u123 tx-sender 'ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM)) ) ;; Returns (ok true)
- Input:
-
with-stacking- Input:
amount:uint: The amount of uSTX that can be locked.
- Output: Not applicable
- Signature:
(with-stacking amount) - Description: Adds a stacking allowance for
amountuSTX from the
asset-ownerof the enclosingrestrict-assets?oras-contract?
expression. This restricts calls todelegate-stxandstack-stxin the
active PoX contract to lock up to the amount of uSTX specified. - Example:
(restrict-assets? tx-sender ((with-stacking u1000000000000)) (try! (contract-call? 'SP000000000000000000002Q6VF78.pox-4 delegate-stx u1100000000000 'ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM none none )) ) ;; Returns (err 0) (restrict-assets? tx-sender ((with-stacking u1000000000000)) (try! (contract-call? 'SP000000000000000000002Q6VF78.pox-4 delegate-stx u900000000000 'ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM none none )) ) ;; Returns (ok true)
- Input:
-
as-contract?-
Input:
((with-stx|with-ft|with-nft|with-stacking)*): The set of allowances to
grant during the evaluation of the body expressions.AnyType* A: The Clarity expressions to be executed within the context,
with the final expression returning typeA, whereAis not a
response
-
Output:
(response A int) -
Signature:
(as-contract? ((with-stx|with-ft|with-nft|with-stacking)*) expr-body1 expr-body2 ... expr-body-last) -
Description: Switches the current context's
tx-senderand
contract-callervalues to the contract's principal and executes the body
expressions within that context, then checks the asset outflows from the
contract against the granted allowances, in declaration order. If any
allowance is violated, the body expressions are reverted, an error is
returned, and an event is emitted with the full details of the violation to
help with debugging. Note that the allowance setup expressions are evaluated
before executing the body expressions. The final body expression cannot
return aresponsevalue in order to avoid returning a nestedresponse
value from therestrict-assets?(nested responses are error-prone).
Returns:(ok x)if the outflows are within the allowances, wherexis the
result of thebodyexpression and has typeA.(err index)if an allowance was violated, whereindexis the 0-based
index of the first violated allowance in the list of granted allowances, or -1
if an asset with no allowance caused the violation.
-
Example:
(define-public (foo) (as-contract? () (try! (stx-transfer? u1000000 tx-sender recipient)) ) ) ;; Returns (err -1) (define-public (bar) (as-contract? ((with-stx u1000000)) (try! (stx-transfer? u1000000 tx-sender recipient)) ) ) ;; Returns (ok true)
-
See SIP proposal
Metadata
Metadata
Assignees
Labels
Type
Projects
Status