Platform: Code4rena
Start Date: 13/11/2023
Pot Size: $24,500 USDC
Total HM: 3
Participants: 120
Period: 4 days
Judge: 0xTheC0der
Id: 306
League: ETH
Rank: 15/120
Findings: 1
Award: $690.37
🌟 Selected for report: 0
🚀 Solo Findings: 0
690.3741 USDC - $690.37
Detailed description of the impact of this finding. The asD contract implement's withdrawCarry() method, which calculates the accrued interest on the users NOTE deposit. The variable maximumWithdrawable gets interest accrued by the deposit by the formulae:(cNote.balanceOf(address(this)*exchangeRate)/1e28-totalSupply,while the formulae is logically correct the scaling factor 1e28 is not, the exchange Rate of the cNote is scaled by 1e18.Using the 1e28 scaling factor would lead to an underflow revert. For instance the current exchangeRate for the cNote is 1004187076354695752,dividing by 1e28 would result 1e-10 which would round down to zero. The result of this implementation is that asD creators would never be able to claim interest accrued.
Provide direct links to all referenced code in GitHub. Add screenshots, logs, or any other relevant proof that illustrates the concept. //SPDX-License-Identifier:UNLICENSED pragma solidity ^0.8;
import "forge-std/Test.sol"; import "src/asD.sol";
contract asDTest is Test { CErc20Interface cNote = CErc20Interface(0xEe602429Ef7eCe0a13e4FfE8dBC16e101049504C);
IERC20 Note = IERC20(0x4e71A2E537B7f9D9413D3991D37958c0b5e1e503); asD asd; address bob = makeAddr("Bob"); address alice = makeAddr("Alice"); address peter = makeAddr("Peter"); function setUp() external { vm.createSelectFork(vm.envString("CANTO_RPC_URL")); asd = new asD("Application ... blah", "asD", address(this), address(cNote), address(this)); } function testWithdrawalCarry() external { //Bob adds token to the pool vm.roll(6000000); uint256 amountReceived = mint(bob, 1e18); console.log("Amount Received:", amountReceived); //fast forward with vm.roll(6917177); asd.withdrawCarry(1e8); } function mint(address user, uint256 _amount) internal returns (uint256 amount) { vm.startPrank(user); deal(address(Note), user, _amount); Note.approve(address(asd), _amount); asd.mint(_amount); amount = IERC20(address(cNote)).balanceOf(address(asd)); vm.stopPrank(); }
} //Logs Running 1 test for src/test/asDEdge.t.sol:asDTest [FAIL. Reason: Arithmetic over/underflow] testWithdrawalCarry() (gas: 300172) Test result: FAILED. 0 passed; 1 failed; 0 skipped; finished in 9.69s
uint256 maximumWithdrawable = (CTokenInterface(cNote).balanceOf(address(this)) * exchangeRate) / ->> 1e18 - totalSupply();
Other
#0 - c4-pre-sort
2023-11-20T16:16:07Z
minhquanym marked the issue as duplicate of #227
#1 - c4-judge
2023-11-28T22:59:19Z
MarioPoneder marked the issue as satisfactory