Files
dodo-contractV2/contracts/DODOVendingMachine/impl/DVMFunding.sol

109 lines
3.8 KiB
Solidity
Raw Normal View History

2020-10-23 01:16:52 +08:00
/*
Copyright 2020 DODO ZOO.
SPDX-License-Identifier: Apache-2.0
*/
pragma solidity 0.6.9;
pragma experimental ABIEncoderV2;
2020-11-18 17:51:50 +08:00
import {DVMVault} from "./DVMVault.sol";
2020-10-23 01:16:52 +08:00
import {DecimalMath} from "../../lib/DecimalMath.sol";
2020-11-06 16:03:18 +08:00
import {IDODOCallee} from "../../intf/IDODOCallee.sol";
2020-10-23 01:16:52 +08:00
2020-11-18 17:51:50 +08:00
contract DVMFunding is DVMVault {
2020-11-29 17:38:13 +08:00
// ============ Events ============
2020-12-18 01:11:33 +08:00
event BuyShares(address to, uint256 increaseShares, uint256 totalShares);
2020-12-12 15:51:09 +08:00
event SellShares(address payer, address to, uint256 decreaseShares, uint256 totalShares);
2020-11-29 17:38:13 +08:00
// ============ Buy & Sell Shares ============
// buy shares [round down]
2020-11-24 19:18:03 +08:00
function buyShares(address to)
external
preventReentrant
returns (
uint256 shares,
2020-11-29 17:38:13 +08:00
uint256 baseInput,
uint256 quoteInput
2020-11-24 19:18:03 +08:00
)
{
2020-11-29 17:38:13 +08:00
uint256 baseBalance = _BASE_TOKEN_.balanceOf(address(this));
uint256 quoteBalance = _QUOTE_TOKEN_.balanceOf(address(this));
2020-11-23 10:43:12 +08:00
uint256 baseReserve = _BASE_RESERVE_;
2020-11-18 17:51:50 +08:00
uint256 quoteReserve = _QUOTE_RESERVE_;
2020-11-29 17:38:13 +08:00
baseInput = baseBalance.sub(baseReserve);
quoteInput = quoteBalance.sub(quoteReserve);
require(baseInput > 0, "NO_BASE_INPUT");
// Round down when withdrawing. Therefore, never be a situation occuring balance is 0 but totalsupply is not 0
// But May Happenreserve >0 But totalSupply = 0
2020-11-24 19:18:03 +08:00
if (totalSupply == 0) {
// case 1. initial supply
2020-12-15 01:07:15 +08:00
shares = baseBalance; // 以免出现balance很大但shares很小的情况
2024-02-06 18:00:59 +08:00
require(_QUOTE_TARGET_ > 0, "QUOTE_TARGET_IS_ZERO");
require(shares > 2001, "MINT_AMOUNT_NOT_ENOUGH");
_mint(address(0), 1001);
shares -= 1001;
2020-11-24 19:18:03 +08:00
} else if (baseReserve > 0 && quoteReserve == 0) {
// case 2. supply when quote reserve is 0
2020-11-26 21:03:36 +08:00
shares = baseInput.mul(totalSupply).div(baseReserve);
2020-11-24 19:18:03 +08:00
} else if (baseReserve > 0 && quoteReserve > 0) {
// case 3. normal case
2020-10-27 02:53:23 +08:00
uint256 baseInputRatio = DecimalMath.divFloor(baseInput, baseReserve);
uint256 quoteInputRatio = DecimalMath.divFloor(quoteInput, quoteReserve);
2020-11-24 19:18:03 +08:00
uint256 mintRatio = quoteInputRatio < baseInputRatio ? quoteInputRatio : baseInputRatio;
2020-11-26 21:03:36 +08:00
shares = DecimalMath.mulFloor(totalSupply, mintRatio);
2020-10-27 02:53:23 +08:00
}
2020-11-26 21:03:36 +08:00
_mint(to, shares);
2020-12-30 12:23:52 +08:00
_setReserve(baseBalance, quoteBalance);
2020-11-29 17:38:13 +08:00
emit BuyShares(to, shares, _SHARES_[to]);
2020-10-23 01:16:52 +08:00
}
2020-11-29 17:38:13 +08:00
// sell shares [round down]
2020-11-24 19:18:03 +08:00
function sellShares(
uint256 shareAmount,
address to,
2020-11-27 15:35:36 +08:00
uint256 baseMinAmount,
uint256 quoteMinAmount,
2020-11-29 23:40:19 +08:00
bytes calldata data,
uint256 deadline
2020-11-24 19:18:03 +08:00
) external preventReentrant returns (uint256 baseAmount, uint256 quoteAmount) {
2020-12-01 00:02:33 +08:00
require(deadline >= block.timestamp, "TIME_EXPIRED");
2020-11-29 23:40:19 +08:00
require(shareAmount <= _SHARES_[msg.sender], "DLP_NOT_ENOUGH");
require(to != address(this), "SELL_BACK_NOT_ALLOWED");
2020-11-29 17:38:13 +08:00
uint256 baseBalance = _BASE_TOKEN_.balanceOf(address(this));
uint256 quoteBalance = _QUOTE_TOKEN_.balanceOf(address(this));
2020-11-18 17:51:50 +08:00
uint256 totalShares = totalSupply;
2020-11-29 17:38:13 +08:00
2020-11-23 22:33:23 +08:00
baseAmount = baseBalance.mul(shareAmount).div(totalShares);
quoteAmount = quoteBalance.mul(shareAmount).div(totalShares);
2020-11-29 17:38:13 +08:00
require(
baseAmount >= baseMinAmount && quoteAmount >= quoteMinAmount,
"WITHDRAW_NOT_ENOUGH"
);
2020-11-24 19:18:03 +08:00
_burn(msg.sender, shareAmount);
2020-11-18 17:51:50 +08:00
_transferBaseOut(to, baseAmount);
_transferQuoteOut(to, quoteAmount);
2020-12-07 16:31:58 +08:00
_sync();
2020-12-10 20:45:38 +08:00
2020-11-24 19:18:03 +08:00
if (data.length > 0) {
IDODOCallee(to).DVMSellShareCall(
msg.sender,
shareAmount,
baseAmount,
quoteAmount,
data
);
}
2020-12-10 20:45:38 +08:00
2020-11-30 00:04:57 +08:00
emit SellShares(msg.sender, to, shareAmount, _SHARES_[msg.sender]);
2020-10-23 01:16:52 +08:00
}
}