nftproxy&&register&&fix

This commit is contained in:
owen05
2021-04-04 01:05:08 +08:00
parent 8ce872f4de
commit da5e9dd8e3
12 changed files with 515 additions and 148 deletions

View File

@@ -27,7 +27,11 @@ contract NFTCollateralVault is InitializableOwnable, IERC721Receiver, IERC1155Re
}
NftInfo[] public nftInfos;
constructor (string memory _name) public {
function init(
address owner,
string memory _name
) external {
initOwner(owner);
name = _name;
}

View File

@@ -6,10 +6,12 @@
*/
pragma solidity 0.6.9;
pragma experimental ABIEncoderV2;
interface ICollateralVault {
function _OWNER_() external returns (address);
function transferOwner(address to) external;
function init(address owner, string memory name) external;
function directTransferOwnership(address newOwner) external;
}

View File

@@ -11,10 +11,9 @@ import {SafeMath} from "../lib/SafeMath.sol";
import {DecimalMath} from "../lib/DecimalMath.sol";
import {IERC20} from "../intf/IERC20.sol";
import {SafeERC20} from "../lib/SafeERC20.sol";
import {InitializableOwnable} from "../lib/InitializableOwnable.sol";
import {Ownable} from "../lib/Ownable.sol";
contract FeeDistributor is InitializableOwnable {
contract FeeDistributor {
using SafeMath for uint256;
using SafeERC20 for IERC20;
@@ -24,46 +23,55 @@ contract FeeDistributor is InitializableOwnable {
address public _QUOTE_TOKEN_;
uint256 public _BASE_RESERVE_;
uint256 public _QUOTE_RESERVE_;
uint256 public _BASE_REWARD_RATIO_;
uint256 public _QUOTE_REWARD_RATIO_;
address public _STAKE_VAULT_;
address public _STAKE_TOKEN_;
uint256 public _STAKE_RESERVE_;
mapping(address => uint256) internal _BASE_DEBT_;
mapping(address => uint256) internal _QUOTE_DEBT_;
mapping(address => uint256) internal _SHARES_;
uint256 public _BASE_REWARD_RATIO_;
mapping(address => uint256) internal _USER_BASE_REWARDS_;
mapping(address => uint256) internal _USER_BASE_PER_SHARE_;
uint256 public _QUOTE_REWARD_RATIO_;
mapping(address => uint256) internal _USER_QUOTE_REWARDS_;
mapping(address => uint256) internal _USER_QUOTE_PER_SHARE_;
mapping(address => uint256) internal _SHARES_;
bool internal _FEE_INITIALIZED_;
function init(
address baseToken,
address quoteToken,
address stakeToken
) external {
require(!_FEE_INITIALIZED_, "ALREADY_INITIALIZED");
_FEE_INITIALIZED_ = true;
_BASE_TOKEN_ = baseToken;
_QUOTE_TOKEN_ = quoteToken;
_STAKE_TOKEN_ = stakeToken;
_BASE_REWARD_RATIO_ = DecimalMath.ONE;
_QUOTE_REWARD_RATIO_ = DecimalMath.ONE;
_STAKE_VAULT_ = address(new StakeVault());
}
//TODO: 用户的手续费base or quote 直接转到该合约中stakeVault保存的是
function stake(address to) external {
_accuReward();
_updateGlobalState();
_updateUserReward(to);
uint256 stakeVault = IERC20(_STAKE_TOKEN_).balanceOf(_STAKE_VAULT_);
uint256 stakeInput = stakeVault.sub(_STAKE_RESERVE_);
_addShares(stakeInput, to);
}
function claim(address to) external {
_accuReward();
_updateGlobalState();
_updateUserReward(msg.sender);
_claim(msg.sender, to);
}
function unstake(uint256 amount, address to, bool withClaim) external {
require(_SHARES_[msg.sender]>=amount, "STAKE BALANCE ONT ENOUGH");
_accuReward();
_updateGlobalState();
_updateUserReward(msg.sender);
if (withClaim) {
_claim(msg.sender, to);
@@ -73,30 +81,18 @@ contract FeeDistributor is InitializableOwnable {
StakeVault(_STAKE_VAULT_).transferOut(_STAKE_TOKEN_, amount, to);
}
// ============ Internal ============
function _claim(address sender, address to) internal {
uint256 allBase = DecimalMath.mulFloor(_SHARES_[sender], _BASE_REWARD_RATIO_);
uint256 allQuote = DecimalMath.mulFloor(_SHARES_[sender], _QUOTE_REWARD_RATIO_);
IERC20(_BASE_TOKEN_).safeTransfer(to, allBase.sub(_BASE_DEBT_[sender]));
IERC20(_QUOTE_TOKEN_).safeTransfer(to, allQuote.sub(_QUOTE_DEBT_[sender]));
_BASE_DEBT_[sender] = allBase;
_QUOTE_DEBT_[sender] = allQuote;
uint256 allBase = _USER_BASE_REWARDS_[sender];
uint256 allQuote = _USER_QUOTE_REWARDS_[sender];
IERC20(_BASE_TOKEN_).safeTransfer(to, allBase);
IERC20(_QUOTE_TOKEN_).safeTransfer(to, allQuote);
_USER_BASE_REWARDS_[sender] = 0;
_USER_BASE_REWARDS_[sender] = 0;
}
function _addShares(uint256 amount, address to) internal {
_SHARES_[to] = _SHARES_[to].add(amount);
_BASE_DEBT_[to] = _BASE_DEBT_[to].add(DecimalMath.mulCeil(amount, _BASE_REWARD_RATIO_));
_QUOTE_DEBT_[to] = _QUOTE_DEBT_[to].add(DecimalMath.mulCeil(amount, _QUOTE_REWARD_RATIO_));
_STAKE_RESERVE_ = IERC20(_STAKE_TOKEN_).balanceOf(_STAKE_VAULT_);
}
function _removeShares(uint256 amount, address from) internal {
_SHARES_[from] = _SHARES_[from].sub(amount);
_BASE_DEBT_[from] = _BASE_DEBT_[from].sub(DecimalMath.mulFloor(amount, _BASE_REWARD_RATIO_));
_QUOTE_DEBT_[from] = _QUOTE_DEBT_[from].sub(DecimalMath.mulFloor(amount, _QUOTE_REWARD_RATIO_));
_STAKE_RESERVE_ = IERC20(_STAKE_TOKEN_).balanceOf(_STAKE_VAULT_);
}
function _accuReward() internal {
function _updateGlobalState() internal {
uint256 baseInput = IERC20(_BASE_TOKEN_).balanceOf(address(this)).sub(_BASE_RESERVE_);
uint256 quoteInput = IERC20(_QUOTE_TOKEN_).balanceOf(address(this)).sub(_QUOTE_RESERVE_);
_BASE_REWARD_RATIO_ = _BASE_REWARD_RATIO_.add(DecimalMath.divFloor(baseInput, _STAKE_RESERVE_));
@@ -105,6 +101,31 @@ contract FeeDistributor is InitializableOwnable {
_QUOTE_RESERVE_ = _QUOTE_RESERVE_.add(quoteInput);
}
function _updateUserReward(address user) internal {
_USER_BASE_REWARDS_[user] = DecimalMath.mulFloor(
_SHARES_[user],
_BASE_REWARD_RATIO_.sub(_USER_BASE_PER_SHARE_[user])
).add(_USER_BASE_REWARDS_[user]);
_USER_BASE_PER_SHARE_[user] = _BASE_REWARD_RATIO_;
_USER_QUOTE_REWARDS_[user] = DecimalMath.mulFloor(
_SHARES_[user],
_QUOTE_REWARD_RATIO_.sub(_USER_QUOTE_PER_SHARE_[user])
).add(_USER_QUOTE_REWARDS_[user]);
_USER_QUOTE_PER_SHARE_[user] = _QUOTE_REWARD_RATIO_;
}
function _addShares(uint256 amount, address to) internal {
_SHARES_[to] = _SHARES_[to].add(amount);
_STAKE_RESERVE_ = IERC20(_STAKE_TOKEN_).balanceOf(_STAKE_VAULT_);
}
function _removeShares(uint256 amount, address from) internal {
_SHARES_[from] = _SHARES_[from].sub(amount);
_STAKE_RESERVE_ = IERC20(_STAKE_TOKEN_).balanceOf(_STAKE_VAULT_);
}
}
contract StakeVault is Ownable {

View File

@@ -1,97 +0,0 @@
/*
Copyright 2020 DODO ZOO.
SPDX-License-Identifier: Apache-2.0
*/
pragma solidity 0.6.9;
pragma experimental ABIEncoderV2;
import {InitializableOwnable} from "../lib/InitializableOwnable.sol";
import {ICloneFactory} from "../lib/CloneFactory.sol";
import {IDVM} from "../DODOVendingMachine/intf/IDVM.sol";
// 这一部分最后写,先把前面的接口定下来
// 业务流程没有NFT的情况下
// 1. 上传媒体创建NFTCollateralVault
// 2. 把CollateralVault提供给FragmentFactory做碎片化
// 已经有NFT的情况下
// 1. 将NFT打包成NFTCollateralVault
// 2. 把CollateralVault提供给FragmentFactory做碎片化
// 所以总体来说factory只需要处理vault已经建立好之后的拼装工作即可
interface IFragmentFactory {
function createFragment() external returns (address newVendingMachine);
}
contract FragmentFactory is InitializableOwnable {
// ============ Templates ============
address public immutable _CLONE_FACTORY_;
address public immutable _MT_FEE_RATE_MODEL_;
address public _DVM_TEMPLATE_;
address public _FEE_DISTRIBUTOR_TEMPLATE_;
address public _FRAGMENT_TEMPLATE_;
// ============ Registry ============
// base -> quote -> DVM address list
mapping(address => mapping(address => address[])) public _REGISTRY_;
// creator -> DVM address list
mapping(address => address[]) public _USER_REGISTRY_;
// ============ Functions ============
constructor(
address cloneFactory,
address dvmTemplate,
address feeDistributorTemplate,
address fragmentTemplate,
address mtFeeRateModel
) public {
_CLONE_FACTORY_ = cloneFactory;
_DVM_TEMPLATE_ = dvmTemplate;
_FEE_DISTRIBUTOR_TEMPLATE_ = feeDistributorTemplate;
_FRAGMENT_TEMPLATE_ = fragmentTemplate;
_MT_FEE_RATE_MODEL_ = mtFeeRateModel;
}
function createFragment(
address owner,
address vault,
address quoteToken,
uint256 mtFeeRate,
uint256 i,
uint256 k,
uint256 totalSupply,
uint256 ownerRatio,
uint256 buyoutTimestamp
) external returns (address newFragment) {
// newFragment = ICloneFactory(_CLONE_FACTORY_).clone(_FRAGMENT_TEMPLATE_);
// newVendingMachine = ICloneFactory(_CLONE_FACTORY_).clone(_DVM_TEMPLATE_);
// newFeeDistributor = ICloneFactory(_CLONE_FACTORY_).clone(_FEE_DISTRIBUTOR_TEMPLATE_);
// {
// IFeeDistributor(newFeeDistributor).init(newFragment, quoteToken, newFragment);
// }
// {
// IDVM(newVendingMachine).init(
// newFeeDistributor,
// newFragment,
// quoteToken,
// 0,
// mtFeeRateModel,
// i,
// k,
// false
// );
// IFeeRateRegistry(mtFeeRateModel).set(newVendingMachine, mtFeeRate);
// }
// {
// IFragment(newFragment).init(owner, newVendingMachine, vault, totalSupply, ownerRatio, buyoutTimestamp);
// }
}
}

View File

@@ -0,0 +1,86 @@
/*
Copyright 2020 DODO ZOO.
SPDX-License-Identifier: Apache-2.0
*/
pragma solidity 0.6.9;
pragma experimental ABIEncoderV2;
import {InitializableOwnable} from "../../lib/InitializableOwnable.sol";
interface IDODONFTRegistry {
function addRegistry(
address vault,
address fragment,
address feeDistributor,
address dvm
) external;
}
/**
* @title DODONFT Registry
* @author DODO Breeder
*
* @notice Register DODONFT Pools
*/
contract DODONFTRegistry is InitializableOwnable {
mapping (address => bool) public isAdminListed;
// ============ Registry ============
// Frag -> FeeDistributor
mapping(address => address) public _FRAG_FEE_REGISTRY_;
// DVM -> FeeDistributor
mapping(address => address) public _DVM_FEE_REGISTRY_;
// Vault -> Frag
mapping(address => address) public _VAULT_FRAG_REGISTRY_;
// ============ Events ============
event NewRegistry(
address vault,
address fragment,
address feeDistributor,
address dvm
);
event RemoveRegistry(address fragment);
// ============ Admin Operation Functions ============
function addRegistry(
address vault,
address fragment,
address feeDistributor,
address dvm
) external {
require(isAdminListed[msg.sender], "ACCESS_DENIED");
_FRAG_FEE_REGISTRY_[fragment] = feeDistributor;
_DVM_FEE_REGISTRY_[dvm] = feeDistributor;
_VAULT_FRAG_REGISTRY_[vault] = fragment;
emit NewRegistry(vault, fragment, feeDistributor, dvm);
}
function removeRegistry(
address vault,
address fragment,
address dvm
) external onlyOwner {
_FRAG_FEE_REGISTRY_[fragment] = address(0);
_DVM_FEE_REGISTRY_[dvm] = address(0);
_VAULT_FRAG_REGISTRY_[vault] = address(0);
emit RemoveRegistry(fragment);
}
function addAmindList (address contractAddr) public onlyOwner {
isAdminListed[contractAddr] = true;
}
function removeWhiteList (address contractAddr) public onlyOwner {
isAdminListed[contractAddr] = false;
}
}

View File

@@ -0,0 +1,85 @@
/*
Copyright 2020 DODO ZOO.
SPDX-License-Identifier: Apache-2.0
*/
//TODO:
pragma solidity 0.6.9;
pragma experimental ABIEncoderV2;
import {ICloneFactory} from "../lib/CloneFactory.sol";
import {InitializableERC20} from "../external/ERC20/InitializableERC20.sol";
import {InitializableMintableERC20} from "../external/ERC20/InitializableMintableERC20.sol";
/**
* @title DODO TokenFactory
* @author DODO Breeder
*
* @notice Help user to create erc20 && erc721 && erc1155 token
*/
contract TokenFacotry {
// ============ Templates ============
address public immutable _CLONE_FACTORY_;
address public immutable _ERC20_TEMPLATE_;
address public immutable _MINTABLE_ERC20_TEMPLATE_;
// ============ Events ============
event NewERC20(address erc20, address creator, bool isMintable);
// ============ Registry ============
// creator -> token address list
mapping(address => address[]) public _USER_STD_REGISTRY_;
// ============ Functions ============
constructor(
address cloneFactory,
address erc20Template,
address mintableErc20Template
) public {
_CLONE_FACTORY_ = cloneFactory;
_ERC20_TEMPLATE_ = erc20Template;
_MINTABLE_ERC20_TEMPLATE_ = mintableErc20Template;
}
function createStdERC20(
uint256 totalSupply,
string memory name,
string memory symbol,
uint256 decimals
) external returns (address newERC20) {
newERC20 = ICloneFactory(_CLONE_FACTORY_).clone(_ERC20_TEMPLATE_);
InitializableERC20(newERC20).init(msg.sender, totalSupply, name, symbol, decimals);
_USER_STD_REGISTRY_[msg.sender].push(newERC20);
emit NewERC20(newERC20, msg.sender, false);
}
function createMintableERC20(
uint256 initSupply,
string memory name,
string memory symbol,
uint256 decimals
) external returns (address newMintableERC20) {
newMintableERC20 = ICloneFactory(_CLONE_FACTORY_).clone(_MINTABLE_ERC20_TEMPLATE_);
InitializableMintableERC20(newMintableERC20).init(
msg.sender,
initSupply,
name,
symbol,
decimals
);
emit NewERC20(newMintableERC20, msg.sender, true);
}
function getTokenByUser(address user)
external
view
returns (address[] memory tokens)
{
return _USER_STD_REGISTRY_[user];
}
}

View File

@@ -7,17 +7,14 @@
pragma solidity 0.6.9;
import {SafeMath} from "../lib/SafeMath.sol";
import {SafeERC20} from "../lib/SafeERC20.sol";
import {DecimalMath} from "../lib/DecimalMath.sol";
import {IDVM} from "../DODOVendingMachine/intf/IDVM.sol";
import {IERC20} from "../intf/IERC20.sol";
import {InitializableERC20} from "../external/ERC20/InitializableERC20.sol";
interface ICollateralVault {
function directTransferOwnership(address newOwner) external;
}
import {SafeMath} from "../../lib/SafeMath.sol";
import {SafeERC20} from "../../lib/SafeERC20.sol";
import {DecimalMath} from "../../lib/DecimalMath.sol";
import {IDVM} from "../../DODOVendingMachine/intf/IDVM.sol";
import {IDODOCallee} from "../../intf/IDODOCallee.sol";
import {IERC20} from "../../intf/IERC20.sol";
import {InitializableERC20} from "../../external/ERC20/InitializableERC20.sol";
import {ICollateralVault} from "../../CollateralVault/intf/ICollateralVault.sol";
contract Fragment is InitializableERC20 {
using SafeMath for uint256;
@@ -105,11 +102,20 @@ contract Fragment is InitializableERC20 {
}
function redeem(address to) external {
function redeem(address to, bytes calldata data) external {
require(_IS_BUYOUT_, "DODOFragment: NEED_BUYOUT");
IERC20(_QUOTE_).safeTransfer(to, DecimalMath.mulFloor(_BUYOUT_PRICE_, balances[to]));
_clearBalance(to);
uint256 quoteAmount = DecimalMath.mulFloor(_BUYOUT_PRICE_, balances[msg.sender]);
IERC20(_QUOTE_).safeTransfer(to, quoteAmount);
_clearBalance(msg.sender);
if (data.length > 0) {
IDODOCallee(to).NFTRedeemCall(
msg.sender,
quoteAmount,
data
);
}
}
function getBuyoutRequirement() external view returns (uint256 requireQuote){

View File

@@ -0,0 +1,28 @@
/*
Copyright 2020 DODO ZOO.
SPDX-License-Identifier: Apache-2.0
*/
pragma solidity 0.6.9;
interface IFragment {
function init(
address dvm,
address vaultPreOwner,
address collateralVault,
uint256 totalSupply,
uint256 ownerRatio,
uint256 buyoutTimestamp,
bool isOpenBuyout
) external;
function buyout(address newVaultOwner) external;
function redeem(address to) external;
function _QUOTE_() external view returns (address);
}

View File

@@ -9,6 +9,7 @@ pragma solidity 0.6.9;
pragma experimental ABIEncoderV2;
import {IDODOV2} from "../intf/IDODOV2.sol";
import {IFragment} from "../../GeneralizedFragment/intf/IFragment.sol";
import {IERC20} from "../../intf/IERC20.sol";
import {IWETH} from "../../intf/IWETH.sol";
import {SafeERC20} from "../../lib/SafeERC20.sol";
@@ -64,6 +65,15 @@ contract DODOCalleeHelper is ReentrancyGuard {
_withdraw(assetTo, _quoteToken, quoteAmount, _quoteToken == _WETH_);
}
function NFTRedeemCall(
address payable assetTo,
uint256 quoteAmount,
bytes calldata
) external preventReentrant {
address _quoteToken = IFragment(msg.sender)._QUOTE_();
_withdraw(assetTo, _quoteToken, quoteAmount, _quoteToken == _WETH_);
}
function _withdraw(
address payable to,
address token,

View File

@@ -0,0 +1,195 @@
/*
Copyright 2020 DODO ZOO.
SPDX-License-Identifier: Apache-2.0
*/
pragma solidity 0.6.9;
import {IDODOApproveProxy} from "../DODOApproveProxy.sol";
import {ICloneFactory} from "../../lib/CloneFactory.sol";
import {IERC20} from "../../intf/IERC20.sol";
import {IWETH} from "../../intf/IWETH.sol";
import {InitializableOwnable} from "../../lib/InitializableOwnable.sol";
import {ICollateralVault} from "../../CollateralVault/intf/ICollateralVault.sol";
import {IDODOV2} from "../intf/IDODOV2.sol";
import {IFragment} from "../../GeneralizedFragment/intf/IFragment.sol";
import {IFeeDistributor} from "../../intf/IFeeDistributor.sol";
import {IDODONFTRegistry} from "../../Factory/Registries/DODONFTRegistry.sol";
import {SafeMath} from "../../lib/SafeMath.sol";
import {SafeERC20} from "../../lib/SafeERC20.sol";
import {DecimalMath} from "../../lib/DecimalMath.sol";
import {ReentrancyGuard} from "../../lib/ReentrancyGuard.sol";
/**
* @title DODONFTProxy
* @author DODO Breeder
*
* @notice Entrance of NFT in DODO platform
*/
contract DODONFTProxy is ReentrancyGuard, InitializableOwnable {
using SafeMath for uint256;
// ============ Storage ============
address constant _ETH_ADDRESS_ = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;
address public immutable _WETH_;
address public immutable _DODO_APPROVE_PROXY_;
address public immutable _CLONE_FACTORY_;
address public immutable _DVM_FACTORY_;
address public immutable _NFT_REGISTY_;
address public _VAULT_TEMPLATE_;
address public _FRAG_TEMPLATE_;
address public _FEE_TEMPLATE_;
// ============ Events ============
event ChangeVaultTemplate(address newVaultTemplate);
event ChangeFragTemplate(address newFragTemplate);
event ChangeFeeTemplate(address newFeeTemplate);
event CreateNFTCollateralVault(address creator, address vault);
event CreateFragment(address vault, address fragment, address dvm, address feeDistributor);
event Buyout(address from, address fragment, uint256 amount);
event Stake(address from, address feeDistributor, uint256 amount);
fallback() external payable {}
receive() external payable {}
constructor(
address cloneFactory,
address payable weth,
address dodoApproveProxy,
address dvmFactory,
address vaultTemplate,
address fragTemplate,
address feeTemplate,
address nftRegistry
) public {
_CLONE_FACTORY_ = cloneFactory;
_WETH_ = weth;
_DODO_APPROVE_PROXY_ = dodoApproveProxy;
_DVM_FACTORY_ = dvmFactory;
_VAULT_TEMPLATE_ = vaultTemplate;
_FRAG_TEMPLATE_ = fragTemplate;
_FEE_TEMPLATE_ = feeTemplate;
_NFT_REGISTY_ = nftRegistry;
}
function createNFTCollateralVault(string memory name) external returns (address newVault) {
newVault = ICloneFactory(_CLONE_FACTORY_).clone(_VAULT_TEMPLATE_);
ICollateralVault(newVault).init(msg.sender, name);
emit CreateNFTCollateralVault(msg.sender, newVault);
}
function createFragment(
address quoteToken,
address collateralVault,
address vaultPreOwner,
address stakeToken,
uint256[] calldata dvmParams, //0 - lpFeeRate, 1 - I, 2 - K
uint256[] calldata fragParams, //0 - totalSupply, 1 - ownerRatio, 2 - buyoutTimestamp
bool isOpenBuyout
) external returns (address newFragment, address newDvm, address newFeeDistributor) {
require(msg.sender == collateralVault, "NEED_BE_CALLED_BY_VAULT");
newFragment = ICloneFactory(_CLONE_FACTORY_).clone(_FRAG_TEMPLATE_);
address _quoteToken = quoteToken == _ETH_ADDRESS_ ? _WETH_ : quoteToken;
{
uint256[] memory _dvmParams = dvmParams;
uint256[] memory _fragParams = fragParams;
newDvm = IDODOV2(_DVM_FACTORY_).createDODOVendingMachine(
newFragment,
_quoteToken,
_dvmParams[0],
_dvmParams[1],
_dvmParams[2],
false
);
IFragment(newFragment).init(
newDvm,
vaultPreOwner,
msg.sender,
_fragParams[0],
_fragParams[1],
_fragParams[2],
isOpenBuyout
);
}
ICollateralVault(msg.sender).directTransferOwnership(newFragment);
if(stakeToken == address(0)) {
newFeeDistributor = address(0);
} else {
newFeeDistributor = ICloneFactory(_CLONE_FACTORY_).clone(_FEE_TEMPLATE_);
IFeeDistributor(newFeeDistributor).init(newFragment, _quoteToken, stakeToken);
}
IDODONFTRegistry(_NFT_REGISTY_).addRegistry(msg.sender, newFragment, newFeeDistributor, newDvm);
emit CreateFragment(msg.sender, newFragment, newDvm, newFeeDistributor);
}
function buyout(
address fragment,
uint256 quoteAmount,
uint8 flag // 0 - ERC20, 1 - quoteInETH
) external payable preventReentrant {
_deposit(msg.sender, fragment, IFragment(fragment)._QUOTE_(), quoteAmount, flag == 1);
IFragment(fragment).buyout(msg.sender);
emit Buyout(msg.sender, fragment, quoteAmount);
}
function stakeToFeeDistributor(
address feeDistributor,
uint256 stakeAmount,
uint8 flag // 0 - ERC20, 1 - ETH
) external payable preventReentrant {
_deposit(msg.sender, feeDistributor, IFeeDistributor(feeDistributor)._STAKE_TOKEN_(), stakeAmount, flag == 1);
IFeeDistributor(feeDistributor).stake(msg.sender);
emit Stake(msg.sender, feeDistributor, stakeAmount);
}
//============= Owner ===================
function updateVaultTemplate(address newVaultTemplate) external onlyOwner {
_VAULT_TEMPLATE_ = newVaultTemplate;
emit ChangeVaultTemplate(newVaultTemplate);
}
function updateFragTemplate(address newFragTemplate) external onlyOwner {
_FRAG_TEMPLATE_ = newFragTemplate;
emit ChangeFragTemplate(newFragTemplate);
}
function updateFeeTemplate(address newFeeTemplate) external onlyOwner {
_FEE_TEMPLATE_ = newFeeTemplate;
emit ChangeFeeTemplate(newFeeTemplate);
}
function _deposit(
address from,
address to,
address token,
uint256 amount,
bool isETH
) internal {
if (isETH) {
if (amount > 0) {
IWETH(_WETH_).deposit{value: amount}();
if (to != address(this)) SafeERC20.safeTransfer(IERC20(_WETH_), to, amount);
}
} else {
IDODOApproveProxy(_DODO_APPROVE_PROXY_).claimTokens(token, from, to, amount);
}
}
}

View File

@@ -50,4 +50,10 @@ interface IDODOCallee {
uint256 quoteAmount,
bytes calldata data
) external;
function NFTRedeemCall(
address payable assetTo,
uint256 quoteAmount,
bytes calldata
) external;
}

View File

@@ -0,0 +1,21 @@
/*
Copyright 2020 DODO ZOO.
SPDX-License-Identifier: Apache-2.0
*/
pragma solidity 0.6.9;
interface IFeeDistributor {
function init(
address baseToken,
address quoteToken,
address stakeToken
) external;
function stake(address to) external;
function _STAKE_TOKEN_() external view returns(address);
}