You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Token contracts are able to ensure validity of token interactions by the requirement that account updates of them always have to be included as a parent, for every token interaction.
This only works because we have the 'access' permission!
For default accounts, everyone can include one of their account updates without authorization (common use case: sending someone money without their authorization). The 'access' permission in that case is "none".
Token contracts set their access permission to "proof" or "proofOrSignature". That way, an account update of them always requires a proof. Which ensures that you have to successfully execute a token contract method to approve any token interaction. Usually, the access permission is set to "proof" in the deploy() method.
There is a potential security hole. Imagine someone creates an account, and some time later deploys a token contract to it. In the meantime, the access permission is still "none". An attacker who anticipates that this will become a token contract could mint tokens in the meantime. For example, such an attacker could monitor the mempool for any transactions that look like token contract deployments, and try to frontrun them with a high-fee transaction minting themselves tokens.
The mitigation
A solid defense against this attack is to require the isNew precondition on the same account update that sets the access permission. That means the token contract must be secured from the very start of its account's existence. (The worst case is that the token contract can't be deployed, because an attacker created the account earlier.)
This is a subtle issue, so we should mitigate it by default, otherwise many token contracts would be vulnerable to this attack in practice.
The measure I recommend is to this.account.isNew.requireEquals(Bool(true)) inside the default deploy() on TokenContract.
The text was updated successfully, but these errors were encountered:
The problem
Token contracts are able to ensure validity of token interactions by the requirement that account updates of them always have to be included as a parent, for every token interaction.
This only works because we have the 'access' permission!
For default accounts, everyone can include one of their account updates without authorization (common use case: sending someone money without their authorization). The 'access' permission in that case is "none".
Token contracts set their access permission to "proof" or "proofOrSignature". That way, an account update of them always requires a proof. Which ensures that you have to successfully execute a token contract method to approve any token interaction. Usually, the access permission is set to "proof" in the
deploy()
method.There is a potential security hole. Imagine someone creates an account, and some time later deploys a token contract to it. In the meantime, the access permission is still "none". An attacker who anticipates that this will become a token contract could mint tokens in the meantime. For example, such an attacker could monitor the mempool for any transactions that look like token contract deployments, and try to frontrun them with a high-fee transaction minting themselves tokens.
The mitigation
A solid defense against this attack is to require the
isNew
precondition on the same account update that sets the access permission. That means the token contract must be secured from the very start of its account's existence. (The worst case is that the token contract can't be deployed, because an attacker created the account earlier.)This is a subtle issue, so we should mitigate it by default, otherwise many token contracts would be vulnerable to this attack in practice.
The measure I recommend is to
this.account.isNew.requireEquals(Bool(true))
inside the defaultdeploy()
onTokenContract
.The text was updated successfully, but these errors were encountered: