Fallback audit report

David Kathoh
2 min readOct 10, 2022

Executive summary

This report presents the results of OpenZeppelin Ethernaut CTF smart contracts Code review and security Analysis. The review was conducted on October 8th by David Kathoh.

scope

The review focused on the Fallback smart contract and sought to answer this question :

  • Is it possible to claim ownership of the contract and reduce its balance to 0?

Project Targets

Repository: https://github.com/OpenZeppelin/ethernaut/……

Version: 4f80f8afa47793d9133f03b6c247d8b6b0adc673

Type: Ethereum

Platform: Solidity

Recommendations

Use SafeMath library or upgrade the compiler version to 0.8.X

The compiler version of the smart contract is <0.8.x and the safeMath library is not used, this may lead to integer overflow vulnerability on the arithmetic operation even though there is no way to exploit it in this specific case.

Findings

Each issue has an assigned severity:

  • Minor issues are subjective in nature. They are typically suggestions around best practices or readability. Code maintainers should use their own judgment as to whether to address such issues.
  • Medium issues are objective in nature but are not security vulnerabilities. These should be addressed unless there is a clear reason not to.
  • Major issues are security vulnerabilities that may not be directly exploitable or may require certain conditions in order to be exploited. All major issues should be addressed.
  • Critical issues are directly exploitable security vulnerabilities that need to be fixed.

Ownership transfer condition not checked in receive() function. -Major

Normally, to gain the ownership of the Fallback contract the new owner must contribute more fund than the current contract owner. This condition can be bypassed with the combination of contribute() and the receive() callback function call. First by making a call to contribute() with msg.value < 0.001 ether

function contribute() public payable {
require(msg.value < 0.001 ether);
contributions[msg.sender] += msg.value;
if(contributions[msg.sender] > contributions[owner]) {
owner = msg.sender;
}
}

Then a to call to receive() with msg.value > 0, this will satisfy the conditions in the receive() as the caller contribution is now great than zero.

receive() external payable {
require(msg.value > 0 && contributions[msg.sender] > 0);
owner = msg.sender;
}

The above function will update the owner address and allow the new owner to drain all ether from the smart contract by calling the withdraw() function.

Recommendation

The fix is straightforward and that is to add the same ownership transfer condition from contribute()to receive()

Conclusion

The smart contract within the scope was manually reviewed and analyzed.
As a result of the audit, 1 major severity issue was found in the smart contract and needs to be addressed.

PS: THIS AUDIT IS DONE FOR LEARNING PURPOSES AND THE CODE BASE CONTAINS VULNERABILITY.

--

--

David Kathoh
David Kathoh

No responses yet