Section 5: T-Swap | DeFi Introduction (10:42:39) - Patrick Encountered a TransferFrom Error, but I Received a Deposit Error #186
Replies: 17 comments 184 replies
-
Hello! Thanks for making this issue. Can you:
|
Beta Was this translation helpful? Give feedback.
-
these are the wo contracts 1) Handler.t.sol //SPDX-License-Identifier:MIT
pragma solidity ^0.8.20;
import {Test, console} from "forge-std/Test.sol";
import {StdInvariant} from "forge-std/StdInvariant.sol";
import {HandlerStatefulFuzzCatches} from "../../../src/invariant-break/HandlerStatefulFuzzCatches.sol";
import {MockUSDC} from "../../mocks/MockUSDC.sol";
import {YeildERC20} from "../../mocks/YeildERC20.sol";
import {IERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
contract Handler is StdInvariant,Test{
HandlerStatefulFuzzCatches handlerStatefulFuzzCatches;
YeildERC20 yeildERC20;
MockUSDC mockUSDC;
address user;
constructor(HandlerStatefulFuzzCatches _handlerStatefulFuzzCatches,
YeildERC20 _yeildERC20,
MockUSDC _mockUSDC,
address _user
) {
handlerStatefulFuzzCatches = _handlerStatefulFuzzCatches;
yeildERC20 =_yeildERC20;
mockUSDC = _mockUSDC;
user = _user;
}
function depositYeildERC20(uint256 _amount) public {
uint256 amount = bound(_amount,0,yeildERC20.balanceOf(user));
vm.startPrank(user);
yeildERC20.approve(address(handlerStatefulFuzzCatches),amount);
handlerStatefulFuzzCatches.depositToken(yeildERC20,amount);
vm.stopPrank();
}
function depositMockUSDC(uint256 _amount) public {
uint256 amount = bound(_amount,0,mockUSDC.balanceOf(user));
vm.startPrank(user);
mockUSDC.approve(address(handlerStatefulFuzzCatches),amount);
handlerStatefulFuzzCatches.depositToken(mockUSDC,amount);
vm.stopPrank();
}
function withdrawYeildERC20() public {
vm.startPrank(user);
handlerStatefulFuzzCatches.withdrawToken(yeildERC20);
vm.stopPrank();
}
function withdrawMockUSDC() public {
vm.startPrank(user);
handlerStatefulFuzzCatches.withdrawToken(mockUSDC);
vm.stopPrank();
}
}
and 2) Invariant.t.sol // SPDX-License-Identifier:MIT
pragma solidity ^0.8.20;
import {Test, console} from "forge-std/Test.sol";
import {StdInvariant} from "forge-std/StdInvariant.sol";
import {HandlerStatefulFuzzCatches} from "../../../src/invariant-break/HandlerStatefulFuzzCatches.sol";
import {MockUSDC} from "../../mocks/MockUSDC.sol";
import {YeildERC20} from "../../mocks/YeildERC20.sol";
import {IERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import {Handler} from "./Handler.t.sol";
contract Invariant is StdInvariant, Test {
HandlerStatefulFuzzCatches handlerStatefulFuzzCatches;
MockUSDC mockUSDC;
YeildERC20 yeildERC20;
IERC20[] supposedTokens;
uint256 startingAmount;
address user = makeAddr("user");
Handler handler;
function setUp() external {
vm.startPrank(user);
yeildERC20 = new YeildERC20();
mockUSDC = new MockUSDC();
startingAmount = yeildERC20.INITIAL_SUPPLY();
mockUSDC.mint(user, startingAmount);
vm.stopPrank();
supposedTokens.push(mockUSDC);
supposedTokens.push(yeildERC20);
handlerStatefulFuzzCatches = new HandlerStatefulFuzzCatches(supposedTokens);
targetContract(address(handlerStatefulFuzzCatches));
handler = new Handler(handlerStatefulFuzzCatches,yeildERC20,mockUSDC,user);
bytes4[] memory selectors = new bytes4[](4);
selectors[0] = handler.depositYeildERC20.selector;
selectors[1] = handler.depositMockUSDC.selector;
selectors[2] = handler.withdrawMockUSDC.selector;
selectors[3] = handler.withdrawYeildERC20.selector;
targetSelector(FuzzSelector({addr : address(handler),selectors:selectors }));
}
function statefulFuzz_testInvariantsBreakHandler() public {
vm.startPrank(user);
handlerStatefulFuzzCatches.withdrawToken(mockUSDC);
handlerStatefulFuzzCatches.withdrawToken(yeildERC20);
vm.stopPrank();
assert(mockUSDC.balanceOf(address(handlerStatefulFuzzCatches)) == 0);
assert(yeildERC20.balanceOf(address(handlerStatefulFuzzCatches)) == 0);
assert(yeildERC20.balanceOf(user) == startingAmount);
assert(mockUSDC.balanceOf(user) == startingAmount);
}
}
and this is the error : [⠢] Compiling...
No files changed, compilation skipped
Ran 1 test for test/invariant-break/handler/Invariant.t.sol:Invariant
[FAIL. Reason: custom error 43d95d07:]
[Sequence]
sender=0x00000000000000000000000000000000000025c5 addr=[src/invariant-break/HandlerStatefulFuzzCatches.sol:HandlerStatefulFuzzCatches]0x5615dEB798BB3E4dFa0139dFa1b3D433Cc23b72f calldata=depositToken(address,uint256) args=[0xFAF443257a656507D4b35506c5229DC96050d63E, 183]
statefulFuzz_testInvariantsBreakHandler() (runs: 1, calls: 1, reverts: 1)
Traces:
[3057620] Invariant::setUp()
├─ [0] VM::startPrank(user: [0x6CA6d1e2D5347Bfab1d91e883F1915560e09129D])
│ └─ ← [Return]
├─ [564670] → new YeildERC20@0x7BD1119CEC127eeCDBa5DCA7d1Bd59986f6d7353
│ ├─ emit Transfer(from: 0x0000000000000000000000000000000000000000, to: user: [0x6CA6d1e2D5347Bfab1d91e883F1915560e09129D], value: 1000000000000000000000000 [1e24])
│ └─ ← [Return] 2351 bytes of code
├─ [430367] → new MockUSDC@0x5929B14F2984bBE5309c2eC9E7819060C31c970f
│ └─ ← [Return] 1924 bytes of code
├─ [251] YeildERC20::INITIAL_SUPPLY() [staticcall]
│ └─ ← [Return] 1000000000000000000000000 [1e24]
├─ [46789] MockUSDC::mint(user: [0x6CA6d1e2D5347Bfab1d91e883F1915560e09129D], 1000000000000000000000000 [1e24])
│ ├─ emit Transfer(from: 0x0000000000000000000000000000000000000000, to: user: [0x6CA6d1e2D5347Bfab1d91e883F1915560e09129D], value: 1000000000000000000000000 [1e24])
│ └─ ← [Stop]
├─ [0] VM::stopPrank()
│ └─ ← [Return]
├─ [323357] → new HandlerStatefulFuzzCatches@0x5615dEB798BB3E4dFa0139dFa1b3D433Cc23b72f
│ └─ ← [Return] 1387 bytes of code
├─ [1239699] → new Handler@0x2e234DAe75C793f67A35089C9d99245E1C58470b
│ └─ ← [Return] 5526 bytes of code
└─ ← [Stop]
[2555] HandlerStatefulFuzzCatches::depositToken(0xFAF443257a656507D4b35506c5229DC96050d63E, 183)
└─ ← [Revert] HandlerStatefulFuzzCatches__UnsupportedToken()
Suite result: FAILED. 0 passed; 1 failed; 0 skipped; finished in 14.22ms (3.54ms CPU time)
Ran 1 test suite in 1.69s (14.22ms CPU time): 0 tests passed, 1 failed, 0 skipped (1 total tests)
Failing tests:
Encountered 1 failing test in test/invariant-break/handler/Invariant.t.sol:Invariant
[FAIL. Reason: custom error 43d95d07:]
[Sequence]
sender=0x00000000000000000000000000000000000025c5 addr=[src/invariant-break/HandlerStatefulFuzzCatches.sol:HandlerStatefulFuzzCatches]0x5615dEB798BB3E4dFa0139dFa1b3D433Cc23b72f calldata=depositToken(address,uint256) args=[0xFAF443257a656507D4b35506c5229DC96050d63E, 183]
statefulFuzz_testInvariantsBreakHandler() (runs: 1, calls: 1, reverts: 1)
Encountered a total of 1 failing tests, 0 tests succeeded
rebelbash@LAPTOP-QQLIBCSB:~/f23/security-courses-patrick/sc-exploits-minimized$ forge test --mt statefulFuzz_testInvariantsBreakHandler -vvvv
[⠒] Compiling...
[⠒] Compiling 2 files with 0.8.20
[⠑] Solc 0.8.20 finished in 1.42s
Compiler run successful!
Ran 1 test for test/invariant-break/handler/Invariant.t.sol:Invariant
[FAIL. Reason: custom error 43d95d07:]
[Sequence]
sender=0x0000000000000000000000000000000000000966 addr=[src/invariant-break/HandlerStatefulFuzzCatches.sol:HandlerStatefulFuzzCatches]0x5615dEB798BB3E4dFa0139dFa1b3D433Cc23b72f calldata=depositToken(address,uint256) args=[0xFAF443257a656507D4b35506c5229DC96050d63E, 183]
statefulFuzz_testInvariantsBreakHandler() (runs: 1, calls: 1, reverts: 1)
Traces:
[3057620] Invariant::setUp()
├─ [0] VM::startPrank(user: [0x6CA6d1e2D5347Bfab1d91e883F1915560e09129D])
│ └─ ← [Return]
├─ [564670] → new YeildERC20@0x7BD1119CEC127eeCDBa5DCA7d1Bd59986f6d7353
│ ├─ emit Transfer(from: 0x0000000000000000000000000000000000000000, to: user: [0x6CA6d1e2D5347Bfab1d91e883F1915560e09129D], value: 1000000000000000000000000 [1e24])
│ └─ ← [Return] 2351 bytes of code
├─ [430367] → new MockUSDC@0x5929B14F2984bBE5309c2eC9E7819060C31c970f
│ └─ ← [Return] 1924 bytes of code
├─ [251] YeildERC20::INITIAL_SUPPLY() [staticcall]
│ └─ ← [Return] 1000000000000000000000000 [1e24]
├─ [46789] MockUSDC::mint(user: [0x6CA6d1e2D5347Bfab1d91e883F1915560e09129D], 1000000000000000000000000 [1e24])
│ ├─ emit Transfer(from: 0x0000000000000000000000000000000000000000, to: user: [0x6CA6d1e2D5347Bfab1d91e883F1915560e09129D], value: 1000000000000000000000000 [1e24])
│ └─ ← [Stop]
├─ [0] VM::stopPrank()
│ └─ ← [Return]
├─ [323357] → new HandlerStatefulFuzzCatches@0x5615dEB798BB3E4dFa0139dFa1b3D433Cc23b72f
│ └─ ← [Return] 1387 bytes of code
├─ [1239699] → new Handler@0x2e234DAe75C793f67A35089C9d99245E1C58470b
│ └─ ← [Return] 5526 bytes of code
└─ ← [Stop]
[2555] HandlerStatefulFuzzCatches::depositToken(0xFAF443257a656507D4b35506c5229DC96050d63E, 183)
└─ ← [Revert] HandlerStatefulFuzzCatches__UnsupportedToken()
Suite result: FAILED. 0 passed; 1 failed; 0 skipped; finished in 7.26ms (3.65ms CPU time)
Ran 1 test suite in 1.14s (7.26ms CPU time): 0 tests passed, 1 failed, 0 skipped (1 total tests)
Failing tests:
Encountered 1 failing test in test/invariant-break/handler/Invariant.t.sol:Invariant
[FAIL. Reason: custom error 43d95d07:]
[Sequence]
sender=0x0000000000000000000000000000000000000966 addr=[src/invariant-break/HandlerStatefulFuzzCatches.sol:HandlerStatefulFuzzCatches]0x5615dEB798BB3E4dFa0139dFa1b3D433Cc23b72f calldata=depositToken(address,uint256) args=[0xFAF443257a656507D4b35506c5229DC96050d63E, 183]
statefulFuzz_testInvariantsBreakHandler() (runs: 1, calls: 1, reverts: 1)
Encountered a total of 1 failing tests, 0 tests succeeded when i run this |
Beta Was this translation helpful? Give feedback.
-
and if this does not make sense ,this is the link to it https://github.com/Basha-dude/foundry-security-course-errorGiving-different |
Beta Was this translation helpful? Give feedback.
-
Hello @Basha-dude, Your code is not the same as the code in Patrick's codebase. You can compare your pragma solidity 0.8.20;
import {Test} from "forge-std/Test.sol";
import {StdInvariant} from "forge-std/StdInvariant.sol";
import {HandlerStatefulFuzzCatches} from "../../../src/invariant-break/HandlerStatefulFuzzCatches.sol";
import {YeildERC20} from "../../mocks/YeildERC20.sol";
import {MockUSDC} from "../../mocks/MockUSDC.sol";
import {IERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import {Handler} from "./Handler.t.sol";
contract InvariantBreakHardTest is StdInvariant, Test {
HandlerStatefulFuzzCatches handlerStatefulFuzzCatches;
YeildERC20 yeildERC20;
MockUSDC mockUSDC;
IERC20[] public supportedTokens;
uint256 public startingAmount;
address owner = makeAddr("owner");
Handler handler;
function setUp() public {
vm.startPrank(owner);
// Give our owner 1M tokens each
yeildERC20 = new YeildERC20();
startingAmount = yeildERC20.INITIAL_SUPPLY();
mockUSDC = new MockUSDC();
mockUSDC.mint(owner, startingAmount);
supportedTokens.push(mockUSDC);
supportedTokens.push(yeildERC20);
handlerStatefulFuzzCatches = new HandlerStatefulFuzzCatches(supportedTokens);
vm.stopPrank();
handler = new Handler(handlerStatefulFuzzCatches, yeildERC20, mockUSDC);
bytes4[] memory selectors = new bytes4[](3);
selectors[0] = handler.depositYeildERC20.selector;
selectors[1] = handler.withdrawYeildERC20.selector;
selectors[2] = handler.withdrawMockUSDC.selector;
targetSelector(FuzzSelector({addr: address(handler), selectors: selectors}));
targetContract(address(handler));
}
// THIS however, catches our bug!!!
function statefulFuzz_testInvariantBreakHandler() public {
vm.startPrank(owner);
handlerStatefulFuzzCatches.withdrawToken(mockUSDC);
handlerStatefulFuzzCatches.withdrawToken(yeildERC20);
vm.stopPrank();
assert(mockUSDC.balanceOf(address(handlerStatefulFuzzCatches)) == 0);
assert(yeildERC20.balanceOf(address(handlerStatefulFuzzCatches)) == 0);
assert(mockUSDC.balanceOf(owner) == startingAmount);
assert(yeildERC20.balanceOf(owner) == startingAmount);
}
} |
Beta Was this translation helpful? Give feedback.
-
you can see my code, I did not write this: targetSelector(FuzzSelector({addr: address(handler), selectors: selectors}));
targetContract(address(handler)); i only wrote this targetSelector(FuzzSelector({addr: address(handler), selectors: selectors})); in this // SPDX-License-Identifier:MIT
pragma solidity ^0.8.20;
import {Test, console} from "forge-std/Test.sol";
import {StdInvariant} from "forge-std/StdInvariant.sol";
import {HandlerStatefulFuzzCatches} from "../../../src/invariant-break/HandlerStatefulFuzzCatches.sol";
import {MockUSDC} from "../../mocks/MockUSDC.sol";
import {YeildERC20} from "../../mocks/YeildERC20.sol";
import {IERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import {Handler} from "./Handler.t.sol";
contract Invariant is StdInvariant, Test {
HandlerStatefulFuzzCatches handlerStatefulFuzzCatches;
MockUSDC mockUSDC;
YeildERC20 yeildERC20;
IERC20[] supposedTokens;
uint256 startingAmount;
address user = makeAddr("user");
Handler handler;
function setUp() external {
vm.startPrank(user);
yeildERC20 = new YeildERC20();
mockUSDC = new MockUSDC();
startingAmount = yeildERC20.INITIAL_SUPPLY();
mockUSDC.mint(user, startingAmount);
vm.stopPrank();
supposedTokens.push(mockUSDC);
supposedTokens.push(yeildERC20);
handlerStatefulFuzzCatches = new HandlerStatefulFuzzCatches(supposedTokens);
targetContract(address(handlerStatefulFuzzCatches));
handler = new Handler(handlerStatefulFuzzCatches, yeildERC20, mockUSDC, user);
bytes4[] memory selectors = new bytes4[](4);
selectors[0] = handler.depositYeildERC20.selector;
selectors[1] = handler.depositMockUSDC.selector;
selectors[2] = handler.withdrawMockUSDC.selector;
selectors[3] = handler.withdrawYeildERC20.selector;
targetSelector(FuzzSelector({addr: address(handler), selectors: selectors}));
}
function statefulFuzz_testInvariantsBreakHandler() public {
vm.startPrank(user);
handlerStatefulFuzzCatches.withdrawToken(mockUSDC);
handlerStatefulFuzzCatches.withdrawToken(yeildERC20);
vm.stopPrank();
assert(mockUSDC.balanceOf(address(handlerStatefulFuzzCatches)) == 0);
assert(yeildERC20.balanceOf(address(handlerStatefulFuzzCatches)) == 0);
assert(yeildERC20.balanceOf(user) == startingAmount);
assert(mockUSDC.balanceOf(user) == startingAmount);
}
}
AND thanks for responding 🥰 |
Beta Was this translation helpful? Give feedback.
-
Hey buddy ,I wanted to apologize for doubting your help earlier. I initially thought you was wrong, but I realize now that the mistake was on my end. Thank you for your assistance and for taking the time to help me. I appreciate your expertise and patience. |
Beta Was this translation helpful? Give feedback.
-
will you help me, i don't understand the targetSelector topic
function statefulFuzz_testInvariantsBreakHandler() public {
vm.startPrank(user);
handlerStatefulFuzzCatches.withdrawToken(mockUSDC);
handlerStatefulFuzzCatches.withdrawToken(yeildERC20);
vm.stopPrank();
assert(mockUSDC.balanceOf(address(handlerStatefulFuzzCatches)) == 0);
assert(yeildERC20.balanceOf(address(handlerStatefulFuzzCatches)) == 0);
assert(yeildERC20.balanceOf(user) == startingAmount);
assert(mockUSDC.balanceOf(user) == startingAmount);
}
} i don't understand the how it is withdrawing the tokens without depositing the tokens and In which order the INVARIANT TEST CALLS the selectors randomly or like first, second etc... ? will you explain it |
Beta Was this translation helpful? Give feedback.
-
Thanks for answering, now i understood, Are you working in a job? |
Beta Was this translation helpful? Give feedback.
-
Hey @EngrPips, I want to contribute to open source. Will you guide me on how to contribute? or suggest some open source videos only for web3. |
Beta Was this translation helpful? Give feedback.
-
Hey @EngrPips, I don't even know how to contribute to it., i am very new to it |
Beta Was this translation helpful? Give feedback.
-
@Basha-dude If you see a typo in a code base you can raise a PR to fix this. Then you can move on to bigger issues. |
Beta Was this translation helpful? Give feedback.
-
@EngrPips yeah I did, still it is not logging |
Beta Was this translation helpful? Give feedback.
-
hey @EngrPips , i had a doubt in this // SPDX-License-Identifier: MIT
pragma solidity 0.8.20;
import {Test} from "forge-std/Test.sol";
import {StdInvariant} from "forge-std/StdInvariant.sol";
import {HandlerStatefulFuzzCatches} from "../../../src/invariant-break/HandlerStatefulFuzzCatches.sol";
import {YeildERC20} from "../../mocks/YeildERC20.sol";
import {MockUSDC} from "../../mocks/MockUSDC.sol";
import {IERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import {Handler} from "./Handler.t.sol";
contract InvariantBreakHardTest is StdInvariant, Test {
HandlerStatefulFuzzCatches handlerStatefulFuzzCatches;
YeildERC20 yeildERC20;
MockUSDC mockUSDC;
IERC20[] public supportedTokens;
uint256 public startingAmount;
address owner = makeAddr("owner");
Handler handler;
function setUp() public {
vm.startPrank(owner);
// Give our owner 1M tokens each
yeildERC20 = new YeildERC20();
startingAmount = yeildERC20.INITIAL_SUPPLY();
mockUSDC = new MockUSDC();
mockUSDC.mint(owner, startingAmount);
supportedTokens.push(mockUSDC);
supportedTokens.push(yeildERC20);
handlerStatefulFuzzCatches = new HandlerStatefulFuzzCatches(supportedTokens);
vm.stopPrank();
handler = new Handler(handlerStatefulFuzzCatches, yeildERC20, mockUSDC, owner);
bytes4[] memory selectors = new bytes4[](4);
selectors[0] = handler.depositYeildERC20.selector;
selectors[1] = handler.depositUSDCERC20.selector;
selectors[2] = handler.withdrawMockUSDC.selector;
selectors[3] = handler.withdrawYeildERC20.selector;
targetSelector(FuzzSelector({addr: address(handler), selectors: selectors}));
targetContract(address(handler));
}
// THIS however, catches our bug!!!
function statefulFuzz_testInvariantBreakHandler() public {
vm.startPrank(owner);
handlerStatefulFuzzCatches.withdrawToken(mockUSDC);
handlerStatefulFuzzCatches.withdrawToken(yeildERC20);
vm.stopPrank();
assert(mockUSDC.balanceOf(address(handlerStatefulFuzzCatches)) == 0);
assert(yeildERC20.balanceOf(address(handlerStatefulFuzzCatches)) == 0);
assert(mockUSDC.balanceOf(owner) == startingAmount);
assert(yeildERC20.balanceOf(owner) == startingAmount);
}
} what i understand here is selectors[0] = handler.depositYeildERC20.selector;
selectors[1] = handler.depositUSDCERC20.selector;
selectors[2] = handler.withdrawMockUSDC.selector;
selectors[3] = handler.withdrawYeildERC20.selector; it's get called in a sequence like above and here in this function handlerStatefulFuzzCatches.withdrawToken(mockUSDC);
handlerStatefulFuzzCatches.withdrawToken(yeildERC20); how will it's get called , i just did not understand |
Beta Was this translation helpful? Give feedback.
-
i am trying to do shadow auditing to this contract , but i try to install the packages , it gives me a error of |
Beta Was this translation helpful? Give feedback.
-
Yeah,but it has 26 highs which means got ton to learn |
Beta Was this translation helpful? Give feedback.
-
The title of the submission says, |
Beta Was this translation helpful? Give feedback.
-
Yes, that's correct. Interest in loan protocols is typically time-based. The longer the borrower holds the loan without repaying, the more interest accrues over time. |
Beta Was this translation helpful? Give feedback.
-
https://github.com/Basha-dude/foundry-security-course-errorGiving-different
Beta Was this translation helpful? Give feedback.
All reactions