diff --git a/contracts/GeneralizedFragment/impl/Fragment.sol b/contracts/GeneralizedFragment/impl/Fragment.sol index 6fb629c..cf3e487 100644 --- a/contracts/GeneralizedFragment/impl/Fragment.sol +++ b/contracts/GeneralizedFragment/impl/Fragment.sol @@ -86,7 +86,8 @@ contract Fragment is InitializableERC20 { _BUYOUT_PRICE_ = IDVM(_DVM_).getMidPrice(); uint256 requireQuote = DecimalMath.mulCeil(_BUYOUT_PRICE_, totalSupply); - require(IERC20(_QUOTE_).balanceOf(address(this)) >= requireQuote, "DODOFragment: QUOTE_NOT_ENOUGH"); + uint256 payQuote = IERC20(_QUOTE_).balanceOf(address(this)); + require(payQuote >= requireQuote, "DODOFragment: QUOTE_NOT_ENOUGH"); IDVM(_DVM_).sellShares( IERC20(_DVM_).balanceOf(address(this)), @@ -95,17 +96,14 @@ contract Fragment is InitializableERC20 { 0, "", uint256(-1) - ); + ); + uint256 redeemFrag = totalSupply.sub(balances[address(this)]).sub(balances[_VAULT_PRE_OWNER_]); + uint256 preOwnerQuote = payQuote.sub(DecimalMath.mulCeil(_BUYOUT_PRICE_, redeemFrag)); _clearBalance(address(this)); - - uint256 preOwnerQuote = DecimalMath.mulFloor(_BUYOUT_PRICE_, balances[_VAULT_PRE_OWNER_]); _clearBalance(_VAULT_PRE_OWNER_); - IERC20(_QUOTE_).safeTransfer(_VAULT_PRE_OWNER_, preOwnerQuote); - uint256 newOwnerQuote = DecimalMath.mulFloor(_BUYOUT_PRICE_, balances[newVaultOwner]); - _clearBalance(newVaultOwner); - IERC20(_QUOTE_).safeTransfer(newVaultOwner, newOwnerQuote); + IERC20(_QUOTE_).safeTransfer(_VAULT_PRE_OWNER_, preOwnerQuote); ICollateralVault(_COLLATERAL_VAULT_).directTransferOwnership(newVaultOwner); diff --git a/contracts/GeneralizedFragment/intf/IFragment.sol b/contracts/GeneralizedFragment/intf/IFragment.sol index 995284f..b3caf40 100644 --- a/contracts/GeneralizedFragment/intf/IFragment.sol +++ b/contracts/GeneralizedFragment/intf/IFragment.sol @@ -24,4 +24,8 @@ interface IFragment { function redeem(address to) external; function _QUOTE_() external view returns (address); + + function _DVM_() external view returns (address); + + function totalSupply() external view returns (uint256); } diff --git a/contracts/SmartRoute/proxies/DODONFTProxy.sol b/contracts/SmartRoute/proxies/DODONFTProxy.sol index db9a840..0025145 100644 --- a/contracts/SmartRoute/proxies/DODONFTProxy.sol +++ b/contracts/SmartRoute/proxies/DODONFTProxy.sol @@ -60,6 +60,12 @@ contract DODONFTProxy is ReentrancyGuard, InitializableOwnable { event Buyout(address from, address fragment, uint256 amount); event Stake(address from, address feeDistributor, uint256 amount); + // ============ Modifiers ============ + + modifier judgeExpired(uint256 deadLine) { + require(deadLine >= block.timestamp, "DODONFTProxy: EXPIRED"); + _; + } fallback() external payable {} @@ -147,17 +153,28 @@ contract DODONFTProxy is ReentrancyGuard, InitializableOwnable { function buyout( address fragment, - uint256 quoteAmount, - uint8 flag // 0 - ERC20, 1 - quoteInETH - ) external payable preventReentrant { - if(flag == 1) - require(msg.value == quoteAmount, "DODONFTProxy: VALUE_INVALID"); - else + uint256 quoteMaxAmount, + uint8 flag, // 0 - ERC20, 1 - quoteInETH + uint256 deadLine + ) external payable preventReentrant judgeExpired(deadLine) { + if(flag == 0) require(msg.value == 0, "DODONFTProxy: WE_SAVED_YOUR_MONEY"); - - _deposit(msg.sender, fragment, IFragment(fragment)._QUOTE_(), quoteAmount, flag == 1); + + address dvm = IFragment(fragment)._DVM_(); + uint256 fragTotalSupply = IFragment(fragment).totalSupply(); + uint256 buyPrice = IDVM(dvm).getMidPrice(); + + uint256 curRequireQuote = DecimalMath.mulCeil(buyPrice, fragTotalSupply); + + require(curRequireQuote <= quoteMaxAmount, "DODONFTProxy: CURRENT_TOTAL_VAULE_MORE_THAN_QUOTEMAX"); + + _deposit(msg.sender, fragment, IFragment(fragment)._QUOTE_(), curRequireQuote, flag == 1); IFragment(fragment).buyout(msg.sender); - emit Buyout(msg.sender, fragment, quoteAmount); + + // refund dust eth + if (flag == 1 && msg.value > curRequireQuote) msg.sender.transfer(msg.value - curRequireQuote); + + emit Buyout(msg.sender, fragment, curRequireQuote); } function stakeToFeeDistributor(