codehawks-2023-07-dsc-m08
[M-08] Too many DSC tokens can get minted for fee-on-transfer tokens
Summary
담보 토큰이 fee-on-transfer 토큰일 때 수수료를 떼고 보내는 것을 고려하지 않았다. 실제 예치된 담보보다 많은 양의 담보가 있는 것으로 판단하여 더 많은 DSC를 발행할 수 있다.
Keyword
fee-on-transfer token, erc20, depegging
Vulnerability
담보 토큰이 fee-on-transfer 토큰이면 토큰을 예치할 때 수수료를 지불한다. 하지만 담보 토큰의 수량을 집계할 시 수수료를 제외하지 않는다.
function depositCollateral(address tokenCollateralAddress, uint256 amountCollateral)
public
moreThanZero(amountCollateral)
isAllowedToken(tokenCollateralAddress)
nonReentrant
{
s_collateralDeposited[msg.sender][tokenCollateralAddress] += amountCollateral;
emit CollateralDeposited(msg.sender, tokenCollateralAddress, amountCollateral);
bool success = IERC20(tokenCollateralAddress).transferFrom(msg.sender, address(this), amountCollateral);
if (!success) {
revert DSCEngine__TransferFailed();
}
}이로 인해 실제 컨트랙트에 예치된 담보 토큰보다 많은 담보가 있는 것으로 집계된다. 따라서 유저에게 원래 발행해야 하는 것보다 많은 DSC 토큰을 발행할 수 있다.
Impact
발행해야 하는 것보다 많은 DSC 토큰을 발행하고, 잠재적으로 디페깅을 야기할 수 있다.
Mitigation
실제로 컨트랙트에 예치된 토큰 수를 확인한다.
function depositCollateral(address tokenCollateralAddress, uint256 amountCollateral)
public
moreThanZero(amountCollateral)
isAllowedToken(tokenCollateralAddress)
nonReentrant
{
uint256 balanceBefore = IERC20(tokenCollateralAddress).balanceOf(address(this));
bool success = IERC20(tokenCollateralAddress).transferFrom(msg.sender, address(this), amountCollateral);
uint256 balanceAfter = IERC20(tokenCollateralAddress).balanceOf(address(this));
amountCollateral = balanceAfter - balanceBefore;
if (!success) {
revert DSCEngine__TransferFailed();
}
s_collateralDeposited[msg.sender][tokenCollateralAddress] += amountCollateral;
emit CollateralDeposited(msg.sender, tokenCollateralAddress, amountCollateral);
}tags: bughunting, codehawks, smart contract, solidity, fee-on-transfer token, erc20, depegging, stablecoin, severity medium