A vulnerability was found in the AccountNFT
contract which caused failure (revert) when minting tokens. This vulnerability is caused by a lack of input validation and authorization in these functions, which can cause the contract to not function properly and potentially be misused by irresponsible parties.
mint
function:
This function does not validate whether the recipient (to) address is a null address and whether the given tokenId already exists. This causes a failure when the function is called with invalid input.
_update
function:
This function fails (reverts) when the input is invalid or the authorization is not appropriate. There is insufficient validation of the to and auth parameters, which causes the contract to fail to function properly.
https://github.com/Cyfrin/2024-07-zaros/blob/main/src/account-nft/AccountNFT.sol
Minting Failure
Abuse
Manual review
Foundry
Add Validation to the mint
Function
Fix the _update
Function
PoC
Fuzzing with Foundry:
forge test --match-path test/AccountNFTTest.t.sol
[⠒] Compiling...
[⠢] Compiling 1 files with Solc 0.8.25
[⠆] Solc 0.8.25 finished in 7.00s
Compiler run successful!
proptest: Aborting shrinking after the PROPTEST_MAX_SHRINK_ITERS environment variable or ProptestConfig.max_shrink_iters iterations (set 0 t
o a large(r) value to shrink more; current configuration: 0 iterations) proptest: Aborting shrinking after the PROPTEST_MAX_SHRINK_ITERS environment variable or ProptestConfig.max_shrink_iters iterations (set 0 t
o a large(r) value to shrink more; current configuration: 0 iterations) proptest: Aborting shrinking after the PROPTEST_MAX_SHRINK_ITERS environment variable or ProptestConfig.max_shrink_iters iterations (set 0 t
o a large(r) value to shrink more; current configuration: 0 iterations)
Ran 3 tests for test/AccountNFTTest.t.sol:AccountNFTTest
[FAIL. Reason: EvmError: Revert; counterexample: calldata=0x46360e34000000000000000000000000000000000000000000000000000000000000074400000000
0000000000000000000000000000000000000000000000002f745c58 args=[0x0000000000000000000000000000000000000744, 796154968 [7.961e8]]] testFuzzMint(address,uint256) (runs: 0, μ: 0, ~: 0) [FAIL. Reason: EvmError: Revert; counterexample: calldata=0x3525b6a3000000000000000000000000000000000000000000000000000000000000074400000000
0000000000000000000000000000000000000000000000002f745c5800000000000000000000000000000000000000000000000000000000000000b7 args=[0x0000000000000000000000000000000000000744, 0x000000000000000000000000000000002F745c58, 183]] testFuzzTransfer(address,address,uint256) (runs: 0, μ: 0, ~: 0) [FAIL. Reason: EvmError: Revert; counterexample: calldata=0xe054e2ca000000000000000000000000000000000000000000000000000000000000074400000000
0000000000000000000000000000000000000000000000002f745c5800000000000000000000000000000000000000000000000000000000000000b7 args=[0x0000000000000000000000000000000000000744, 796154968 [7.961e8], 0x00000000000000000000000000000000000000b7]] testFuzzUpdate(address,uint256,address) (runs: 0, μ: 0, ~: 0) Suite result: FAILED. 0 passed; 3 failed; 0 skipped; finished in 4.60ms (9.13ms CPU time)
Ran 1 test suite in 9.76ms (4.60ms CPU time): 0 tests passed, 3 failed, 0 skipped (3 total tests)
Failing tests:
Encountered 3 failing tests in test/AccountNFTTest.t.sol:AccountNFTTest
[FAIL. Reason: EvmError: Revert; counterexample: calldata=0x46360e34000000000000000000000000000000000000000000000000000000000000074400000000
0000000000000000000000000000000000000000000000002f745c58 args=[0x0000000000000000000000000000000000000744, 796154968 [7.961e8]]] testFuzzMint(address,uint256) (runs: 0, μ: 0, ~: 0) [FAIL. Reason: EvmError: Revert; counterexample: calldata=0x3525b6a3000000000000000000000000000000000000000000000000000000000000074400000000
0000000000000000000000000000000000000000000000002f745c5800000000000000000000000000000000000000000000000000000000000000b7 args=[0x0000000000000000000000000000000000000744, 0x000000000000000000000000000000002F745c58, 183]] testFuzzTransfer(address,address,uint256) (runs: 0, μ: 0, ~: 0) [FAIL. Reason: EvmError: Revert; counterexample: calldata=0xe054e2ca000000000000000000000000000000000000000000000000000000000000074400000000
0000000000000000000000000000000000000000000000002f745c5800000000000000000000000000000000000000000000000000000000000000b7 args=[0x0000000000000000000000000000000000000744, 796154968 [7.961e8], 0x00000000000000000000000000000000000000b7]] testFuzzUpdate(address,uint256,address) (runs: 0, μ: 0, ~: 0)
Encountered a total of 3 failing tests, 0 tests succeeded
Test with Foundry:
forge test --match-path test/AccountNFTTest.t.sol
[⠒] Compiling...
[⠢] Compiling 1 files with Solc 0.8.25
[⠆] Solc 0.8.25 finished in 6.04s
Compiler run successful!
Ran 6 tests for test/AccountNFTTest.t.sol:AccountNFTTest
[FAIL. Reason: EvmError: Revert] testMintWithExistingTokenId() (gas: 135928)
[FAIL. Reason: Error != expected error: != ERC721: mint to the zero address] testMintWithInvalidAddress() (gas: 15130)
[FAIL. Reason: EvmError: Revert] testMintWithValidInput() (gas: 135632)
[FAIL. Reason: EvmError: Revert] testTransferWithValidInput() (gas: 135908)
[FAIL. Reason: EvmError: Revert] testTransferWithoutOwnership() (gas: 136181)
[FAIL. Reason: EvmError: Revert] testUpdateWithValidInput() (gas: 135929)
Suite result: FAILED. 0 passed; 6 failed; 0 skipped; finished in 1.43ms (861.00µs CPU time)
Ran 1 test suite in 6.46ms (1.43ms CPU time): 0 tests passed, 6 failed, 0 skipped (6 total tests)
Failing tests:
Encountered 6 failing tests in test/AccountNFTTest.t.sol:AccountNFTTest
[FAIL. Reason: EvmError: Revert] testMintWithExistingTokenId() (gas: 135928)
[FAIL. Reason: Error != expected error: != ERC721: mint to the zero address] testMintWithInvalidAddress() (gas: 15130)
[FAIL. Reason: EvmError: Revert] testMintWithValidInput() (gas: 135632)
[FAIL. Reason: EvmError: Revert] testTransferWithValidInput() (gas: 135908)
[FAIL. Reason: EvmError: Revert] testTransferWithoutOwnership() (gas: 136181)
[FAIL. Reason: EvmError: Revert] testUpdateWithValidInput() (gas: 135929)
Encountered a total of 6 failing tests, 0 tests succeeded
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.