From db499fdd9b6f5f6f08423d0459bd0b7f9848822c Mon Sep 17 00:00:00 2001 From: eagle Date: Tue, 14 Jan 2025 14:49:34 +0530 Subject: [PATCH] feat: use mulDiv --- src/protocol/AssetPool.sol | 18 +++++++++++------- src/protocol/xToken.sol | 11 +++++------ 2 files changed, 16 insertions(+), 13 deletions(-) diff --git a/src/protocol/AssetPool.sol b/src/protocol/AssetPool.sol index c9ec126..4dd20d1 100644 --- a/src/protocol/AssetPool.sol +++ b/src/protocol/AssetPool.sol @@ -6,6 +6,7 @@ pragma solidity ^0.8.20; import "openzeppelin-contracts/contracts/access/Ownable.sol"; import "openzeppelin-contracts/contracts/token/ERC20/IERC20.sol"; import "openzeppelin-contracts/contracts/utils/Pausable.sol"; +import "openzeppelin-contracts/contracts/utils/math/Math.sol"; import {IAssetPool} from "../interfaces/IAssetPool.sol"; import {IXToken} from "../interfaces/IXToken.sol"; import {ILPRegistry} from "../interfaces/ILPRegistry.sol"; @@ -129,8 +130,8 @@ contract AssetPool is IAssetPool, Ownable, Pausable { // Get scaled amount from xToken contract uint256 scaledAmount = assetToken.scaledBalanceOf(msg.sender); - uint256 nominalBalance = assetToken.balanceOf(msg.sender); - uint256 scaledBurnAmount = scaledAmount * xTokenAmount / nominalBalance; + uint256 balance = assetToken.balanceOf(msg.sender); + uint256 scaledBurnAmount = Math.mulDiv(scaledAmount, xTokenAmount, balance); assetToken.burn(msg.sender, xTokenAmount); redemptionScaledRequests[msg.sender] = scaledBurnAmount; @@ -147,11 +148,14 @@ contract AssetPool is IAssetPool, Ownable, Pausable { if (amount == 0) revert NothingToCancel(); uint256 scaledAmount = redemptionScaledRequests[msg.sender]; + + totalRedemptionRequests -= amount; + totalRedemptionScaledRequests -= scaledAmount; + redemptionRequests[msg.sender] = 0; redemptionScaledRequests[msg.sender] = 0; - totalRedemptionRequests -= redemptionRequests[msg.sender]; - totalRedemptionScaledRequests -= scaledAmount; - uint256 price = amount * PRECISION / scaledAmount; + + uint256 price = Math.mulDiv(amount, PRECISION, scaledAmount); assetToken.mint(msg.sender, amount, price); emit BurnCancelled(msg.sender, amount, cycleIndex); @@ -187,8 +191,8 @@ contract AssetPool is IAssetPool, Ownable, Pausable { uint256 spotPrice = assetToken.oracle().assetPrice(); netReserveDelta = int256(totalDepositRequests) - int256(totalRedemptionRequests); newReserveSupply = assetToken.totalSupply() + totalDepositRequests; // Redemptions are already burned so they are not considered - newAssetSupply = newReserveSupply * spotPrice / PRECISION; - rebalanceAmount = int256(totalRedemptionScaledRequests * spotPrice / PRECISION) - int256(totalRedemptionRequests); + newAssetSupply = Math.mulDiv(newReserveSupply, spotPrice, PRECISION); + rebalanceAmount = int256(Math.mulDiv(totalRedemptionScaledRequests, spotPrice, PRECISION)) - int256(totalRedemptionRequests); emit RebalanceInitiated( cycleIndex, diff --git a/src/protocol/xToken.sol b/src/protocol/xToken.sol index b19fc47..b87dd46 100644 --- a/src/protocol/xToken.sol +++ b/src/protocol/xToken.sol @@ -4,6 +4,7 @@ pragma solidity ^0.8.20; import "openzeppelin-contracts/contracts/token/ERC20/ERC20.sol"; +import "openzeppelin-contracts/contracts/utils/math/Math.sol"; import "../interfaces/IAssetOracle.sol"; import "../interfaces/IXToken.sol"; @@ -79,7 +80,7 @@ contract xToken is IXToken, ERC20 { */ function _convertToScaledAmountWithPrice(uint256 amount, uint256 price) internal pure returns (uint256) { if (price == 0) revert InvalidPrice(); - return (amount * PRECISION) / price; + return Math.mulDiv(amount, PRECISION, price); } /** @@ -129,8 +130,8 @@ contract xToken is IXToken, ERC20 { function burn(address account, uint256 amount) external onlyPool { uint256 balance = balanceOf(account); if (balance < amount) revert InsufficientBalance(); - uint256 scaledBalace = _scaledBalances[account]; - uint256 scaledBalanceToBurn = scaledBalace * amount / balance; + uint256 scaledBalance = _scaledBalances[account]; + uint256 scaledBalanceToBurn = Math.mulDiv(scaledBalance, amount, balance); _scaledBalances[account] -= scaledBalanceToBurn; _totalScaledSupply -= scaledBalanceToBurn; @@ -150,14 +151,13 @@ contract xToken is IXToken, ERC20 { if (balance < amount) revert InsufficientBalance(); uint256 scaledBalance = _scaledBalances[msg.sender]; - uint256 scaledBalanceToTransfer = scaledBalance * amount / balance; + uint256 scaledBalanceToTransfer = Math.mulDiv(scaledBalance, amount, balance); _scaledBalances[msg.sender] -= scaledBalanceToTransfer; _scaledBalances[recipient] += scaledBalanceToTransfer; _transfer(msg.sender, recipient, amount); - emit Transfer(msg.sender, recipient, amount); return true; } @@ -189,7 +189,6 @@ contract xToken is IXToken, ERC20 { _transfer(sender, recipient, amount); - emit Transfer(sender, recipient, amount); return true; } } \ No newline at end of file