1/5
_Follow along the course with this video._ --- ### Redeem Collateral Now that we've the means to depositCollateral in our tests, let's write the function to do the opposite, redeemCollateral. We're going to set this up similarly to our depositCollateral function within `Handler.t.sol`. ```solidity function redeemCollateral(uint256 collateralSeed, uint256 amountCollateral) public { ERC20Mock collateral = _getCollateralFromSeed(collateralSeed); } ``` Just like we bound the amountCollateral in our depositCollateral function, we'll need to do so here as well, but this time, the amount needs to be bound to the amount of collateral a user actually has! I added another getter function we can use for this. ```solidity function redeemCollateral(uint256 collateralSeed, uint256 amountCollateral) public { ERC20Mock collateral = _getCollateralFromSeed(collateralSeed); uint256 maxCollateralToRedeem = dsce.getCollateralBalanceOfUser(address(collateral), msg.sender); amountCollateral = bound(amountCollateral, 1, maxCollateralToRedeem); dsce.redeemCollateral(address(collateral), amountCollateral); } ``` Let's run it! ```bash forge test --mt invariant_ProtocolTotalSupplyLessThanCollateralValue -vvvv ``` ::image{src='/foundry-defi/21-defi-handler-redeem-collateral/defi-handler-redeem-collateral1.png' style='width: 100%; height: auto;'} Uh oh, it looks like we're running into an issue when the maxCollateralToRedeem is 0. We can fix this with a small adjustment to our function. We'll set the lower bounds of our `bound` function to `0`, additionally we'll add a conditional which will return if the `maxCollateralToRedeem == 0`. ```solidity function redeemCollateral(uint256 collateralSeed, uint256 amountCollateral) public { ERC20Mock collateral = _getCollateralFromSeed(collateralSeed); uint256 maxCollateralToRedeem = dsce.getCollateralBalanceOfUser(address(collateral), msg.sender); amountCollateral = bound(amountCollateral, 0, maxCollateralToRedeem); if(amountCollateral == 0){ return; } dsce.redeemCollateral(address(collateral), amountCollateral); } ``` ::image{src='/foundry-defi/21-defi-handler-redeem-collateral/defi-handler-redeem-collateral2.png' style='width: 100%; height: auto;'} Woo, nailed it again! Our handler now allows us to test both the depositCollateral and redeemCollateral functionality of our protocol. Through the use of our handler, we've ensured that all the calls to deposit and redeem are going to be valid as well, avoiding reverts and wasted fuzz runs. Something to keep in mind at this point is that `fail_on_revert` flag, however. While writing this test, you can see we've restricted the functionality such that a user is only going to attempt to redeem the collateral that they have. Were there a bug, which allowed users to redeem _more_ than they had, our test wouldn't catch the vulnerability! ### Wrap Up We're crushing these stateful fuzz tests! We've written Handler functions for both our deposit and redeem functionalities within DecentralizedStableCoin.sol. In our testing, we've learnt the pros and cons of the `fail_on_revert` flag and how to be conscious of the false sense of security some of our test configurations may give us. In the next lesson we're hittin the mintDsc function, can't wait!
This lesson delves into the mechanisms of handling collateral in blockchain transactions. It focuses on the implementation and testing of functions for depositing and redeeming collateral, emphasizing the importance of validity checks.
Previous lesson
Previous
Next lesson
Next
Give us feedback
Course Overview
About the course
Advanced smart contract development
How to develop a stablecoin
How to develop a DeFi protocol
How to develop a DAO
Advanced smart contracts testing
Fuzz testing
Manual verification
Web3 Developer Relations
$85,000 - $125,000 (avg. salary)
Web3 developer
$60,000 - $150,000 (avg. salary)
Smart Contract Engineer
$100,000 - $150,000 (avg. salary)
Smart Contract Auditor
$100,000 - $200,000 (avg. salary)
Security researcher
$49,999 - $120,000 (avg. salary)
Guest lecturers:
Juliette Chevalier
Lead Developer relations at Aragon
Nader Dabit
Director of developer relations at EigenLayer
Ally Haire
Developer relations at Protocol Labs
Harrison
Founder at GasliteGG
Last updated on April 4, 2025
Solidity Developer
Advanced FoundryDuration: 36min
Duration: 3h 06min
Duration: 5h 02min
Duration: 6h 02min
Duration: 2h 47min
Duration: 1h 23min
Duration: 4h 28min
Duration: 1h 19min
Duration: 1h 10min
Course Overview
About the course
Advanced smart contract development
How to develop a stablecoin
How to develop a DeFi protocol
How to develop a DAO
Advanced smart contracts testing
Fuzz testing
Manual verification
Web3 Developer Relations
$85,000 - $125,000 (avg. salary)
Web3 developer
$60,000 - $150,000 (avg. salary)
Smart Contract Engineer
$100,000 - $150,000 (avg. salary)
Smart Contract Auditor
$100,000 - $200,000 (avg. salary)
Security researcher
$49,999 - $120,000 (avg. salary)
Guest lecturers:
Juliette Chevalier
Lead Developer relations at Aragon
Nader Dabit
Director of developer relations at EigenLayer
Ally Haire
Developer relations at Protocol Labs
Harrison
Founder at GasliteGG
Last updated on April 4, 2025
Testimonials
Read what our students have to say about this course.
Chainlink
Chainlink
Gustavo Gonzalez
Solutions Engineer at OpenZeppelin
Francesco Andreoli
Lead Devrel at Metamask
Albert Hu
DeForm Founding Engineer
Radek
Senior Developer Advocate at Ceramic
Boidushya
WalletConnect
Idris
Developer Relations Engineer at Axelar