The Ocean contract and onERC1155Received function is vulnerable to read only reentrancy when read from another contract.
The order of function execution when called externally from the onERC1155Received function in the Ocean contract is as follows.
The onERC1155Received Function calls and traverses through the following functions
Ocean.onERC1155Received(address,address,uint256,uint256,bytes) (src/ocean/Ocean.sol#326-343):
State variables read that were written after the external call(s):
- Ocean._ERC1155InteractionStatus (src/ocean/Ocean.sol#108) was read at _ERC1155InteractionStatus == INTERACTION (src/ocean/Ocean.sol#338)
This variable was written at (after external call):
- _ERC1155InteractionStatus = NOT_INTERACTION (src/ocean/Ocean.sol#932)
- Ocean._ERC1155InteractionStatus (src/ocean/Ocean.sol#108) was read at IERC1155Receiver.onERC1155Received.selector (src/ocean/Ocean.sol#339)
This variable was written at (after external call):
- _ERC1155InteractionStatus = NOT_INTERACTION (src/ocean/Ocean.sol#932)
- Ocean._ERC1155InteractionStatus (src/ocean/Ocean.sol#108) was read at 0 (src/ocean/Ocean.sol#341)
This variable was written at (after external call):
- _ERC1155InteractionStatus = NOT_INTERACTION (src/ocean/Ocean.sol#932)
Proof of Concept
The vulnerable function is located in the Ocean contract on lines 324-346 and is called onERC1155Received. Its contents are as follows.
The exploit was built in one of the foundry tests files which is the attacker contract made available to us by shell-protocol in src/test/fork/TestCurve2PoolAdapter.t.sol
The exploit looks like the following POC in Foundry
Lines of code
https://github.com/code-423n4/2023-11-shellprotocol/blob/485de7383cdf88284ee6bcf2926fb7c19e9fb257/src/ocean/Ocean.sol#L326-L343
Vulnerability details
Impact
The Ocean contract and onERC1155Received function is vulnerable to read only reentrancy when read from another contract.
The order of function execution when called externally from the onERC1155Received function in the Ocean contract is as follows.
The onERC1155Received Function calls and traverses through the following functions
Proof of Concept
The vulnerable function is located in the Ocean contract on lines 324-346 and is called onERC1155Received. Its contents are as follows.
The exploit was built in one of the foundry tests files which is the attacker contract made available to us by shell-protocol in
src/test/fork/TestCurve2PoolAdapter.t.sol
The exploit looks like the following POC in Foundry
As proof, the log results show the updated balance as follows.
Tools Used
VS Code. Foundry.
Recommended Mitigation Steps
Use read-only re-entrancy guard.
Assessed type
Reentrancy