15,000 USDC
View results
Submission Details
Severity: medium

Possibility of Front-running attack

Summary

Front-running attack could be possible.

Vulnerability Details

The contract does not have any logic to prevent front-running attacks. This means that an attacker could potentially front-run a transaction by sending a transaction to mint tokens before the owner of the contract sends a transaction to burn tokens.

Impact

This would effectively allow the attacker to steal tokens from the contract.

Tools Used

Manual code review

Recommendations

Here is how to prevent the front-running attack in the Solidity smart contract you provided:

  • Use a transaction counter. A transaction counter is a simple way to prevent front-running attacks. It works by incrementing a counter whenever a state-modifying transaction occurs in the smart contract. This ensures that all transactions are processed in the order in which they were received, regardless of the gas price or nonce of the transaction.

uint256 public transactionCounter;
function burn(uint256 _amount) public override onlyOwner {
transactionCounter++;
...
}
  • Use a commit-reveal scheme. A commit-reveal scheme is a more complex way to prevent front-running attacks. It works by allowing users to commit to a value while keeping it secret from others. Once the user reveals the value, the transaction is processed. This prevents attackers from front-running the transaction by submitting a higher gas price.

struct CommitReveal {
uint256 value;
bytes32 hash;
}
function burn(uint256 _amount) public override onlyOwner {
CommitReveal commitReveal = CommitReveal({
value: _amount,
hash: keccak256(abi.encode(_amount)),
});
...
}
  • Use off-chain ordering. Off-chain ordering is a way to prevent front-running attacks by processing transactions off-chain and then submitting them to the blockchain in a batch. This prevents attackers from front-running the transaction by submitting it to the blockchain before the victim.

contract OffChainOrderer {
event TransactionSubmitted(uint256 transactionId);
function submitTransaction(uint256 _transactionId) public {
emit TransactionSubmitted(_transactionId);
}
}
contract DecentralizedStableCoin is ERC20Burnable, Ownable, OffChainOrderer {
...
function burn(uint256 _amount) public override onlyOwner {
uint256 transactionId = submitTransaction(_amount);
...
}
}

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.