OEP: 10 Title: Cross-contract Call Attack Prevention Standard Author: Wyatt Mufson <wyatt@towerbuilders.org> Type: Standard Status: Accepted Created: 2019-05-25
The OEP-10 Proposal is a standard for cross-contract call attack prevention in digital asset smart contracts.
The motivation for this contract comes from the lack of cross-contract call attack prevention documentation and practices in smart contract development. The current proposals for digital assets on the Ontology blockchain do not address this issue and therefore put users' assets at risk.
It was ultimately inspired by the article An Analysis of Ontology Smart Contract Security and Loopholes — Part 1 and the Caller Validation article by TowerBuilders.
This OEP introduces a process for preventing malicious contracts to invoke smart contracts conforming to OEP-10. By default, users will only be able to invoke the contract directly from their wallet. In order to be able to invoke the contract from another contract they will need to manually approve that second contract. Users will also have the ability to unapprove contracts, as well as view whether a contract has been approved.
This OEP introduces three methods to be implemented within the Main
function: approveContract
, unapproveContract
and isApproved
.
It also introduces an internal method, RequireApproved
to be included within any method that changes the state.
For example, an OEP4 contract that also follows this OEP will call RequireApproved
at the beginning of the transfer
, transferMulti
, approve
and transferFrom
methods.
def approveContract(contractHash)
The approveContract
method takes one argument, the contractHash
to approve.
It will whitelist the smart contract with the hash contractHash
to be used with the given smart contract following OEP10.
approveContract
must also only be called directly by a wallet, the owner of the contract.
If not, this method must throw an exception.
def unapproveContract(contractHash)
The unapproveContract
method takes one argument, the contractHash
.
It will remove the smart contract with the hash contractHash
from the whitelist for the given smart contract following OEP10.
unapproveContract
must also only be called directly by a wallet, the owner of the contract.
If not, this method must throw an exception.
def isApproved(contractHash)
The isApproved
method takes one argument, the contractHash
.
It returns whether the smart contract with the hash contractHash
is in the whitelist for the contract following OEP10.
def RequireApproved()
The RequireApproved
method takes no arguments.
If the results of GetCallingScriptHash()
and GetEntryScriptHash()
do not match, then the callerHash
must be in the whitelist for the wallet.
If not, this method must throw an exception.
This OEP was designed with the usability and security of digital assets on the Ontology blockchain in-mind. The goal is to enable a new type of asset on Ontology that will be optimized for use in smart contracts while maintaining the security of its users. Contracts following this OEP are meant to also be following a standard for other crypto assets - such as OEP4, OEP5 and OEP8.
This OEP is implemented in this example contract.
Note that notProtectedFromCCA
can be called by a malicious contract, while protectedFromCCA
cannot.