The Stabilizer contract is designed to maintain the peg of the stable coin by minting and burning stable coins in exchange for collateral. However, these functions assume a 1:1 ratio between the value of the two tokens without validating their prices against an oracle. This vulnerability enables potential exploiters to steal significant amounts of funds from the protocol when volatile collateral is used. Consider the following scenario:
The Stabilizer contract is deployed with WETH as the collateral token, which has 18 decimals.
Alice holds $500 worth of stable coins (500e18), while the Stabilizer contract holds $3M worth of WETH (1000e18) (assuming 1 ETH = $3000).
Alice calls Stabilizer.sol::burn(500e18), which transfers 475 WETH to her, resulting in a profit of approximately $1.42M for just $500 worth of stable coins (after considering a 5% fee to the protocol).
function burn(uint256 _amount) external {
// mintableToken is 18 decimals, scale accordingly
@> uint256 collateralAmount = _amount / scalingFactor; // @audit Assumes 1:1 ratio with both tokens having 18 decimals
require(_amount >= scalingFactor, "amount-too-small");
uint256 fee = (collateralAmount * feeBps) / 10000;
stableToken.safeTransferFrom(msg.sender, address(this), _amount);
stableToken.burn(_amount);
@> collateralToken.safeTransfer(msg.sender, collateralAmount - fee); // @audit Transfers much more collateral than intended
collateralToken.safeTransfer(feeRecipient, fee);
emit StabilizerBurn(msg.sender, _amount, fee);
}
### Recommendation
Implement an oracle to validate the prices of the provided tokens during both minting and burning operations and adjust accordingly based on their values.
### PoC
To verify the issue, follow this [guide](https://hardhat.org/hardhat-runner/docs/advanced/hardhat-and-foundry) and include this [test](https://gist.github.com/DanailYordanov/53f1f9a906269a80305606247313a162) in the codebase. The test demonstrates the issues encountered during minting and burning.
Context
Stabilizer::mint() Stabilizer::burn()
Description
The
Stabilizer
contract is designed to maintain the peg of the stable coin by minting and burning stable coins in exchange for collateral. However, these functions assume a 1:1 ratio between the value of the two tokens without validating their prices against an oracle. This vulnerability enables potential exploiters to steal significant amounts of funds from the protocol when volatile collateral is used. Consider the following scenario:Stabilizer
contract is deployed with WETH as the collateral token, which has 18 decimals.Stabilizer
contract holds $3M worth of WETH (1000e18) (assuming 1 ETH = $3000).Alice calls
Stabilizer.sol::burn(500e18)
, which transfers 475 WETH to her, resulting in a profit of approximately $1.42M for just $500 worth of stable coins (after considering a 5% fee to the protocol).@> collateralToken.safeTransfer(msg.sender, collateralAmount - fee); // @audit Transfers much more collateral than intended collateralToken.safeTransfer(feeRecipient, fee);
}