-
Notifications
You must be signed in to change notification settings - Fork 9
/
Curve.sol
128 lines (111 loc) · 2.9 KB
/
Curve.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
pragma solidity 0.6.6;
import "./I_Curve.sol";
import "./I_Token.sol";
import "../node_modules/openzeppelin-solidity/contracts/math/SafeMath.sol";
//TODO update to use safe maths
/**
* @author Veronica Coutts @vonnie610 (twitter) @VeronicaLC (GitLab)
* @title Curve
* @notice This curve contract enables an IBCO (Initial Bonding Curve Offering)
* as a mechanism to launch a token into the open market without having
* to raise the funds in a traditional manner.
* This product is a beta. Use at your own risk.
*/
contract Curve is I_Curve {
using SafeMath for uint256;
/**
* This curve uses the following formula:
* a/3(x_1^3 - x_0^3) + b/2(x_1^2 - x_0^2) + c(x_1 - x_0)
* The vaiables (a, b & c) are pulled from the token (msg.sender).
* x_1 and x_0 are the supply and the supply +/- the amount of tokens being
* bought and sold.
*/
/**
* @param _tokens: The number of tokens being bought.
* @return uint256: The cost price of the number of tokens in collateral.
*/
function getBuyPrice(
uint256 _tokens
)
override(I_Curve)
public
view
returns(uint256)
{
uint256 supply = I_Token(msg.sender).totalSupply();
uint256 newSupply = supply.add(_tokens);
uint256 a;
uint256 b;
uint256 c;
(a, b, c) = I_Token(msg.sender).getCurve();
return _getPrice(a, b, c, supply, newSupply);
}
/**
* @param _tokens: The number of tokens being sold.
* @return uint256: The sell price of the number of tokens in collateral.
*/
function getSellAmount(
uint256 _tokens
)
override(I_Curve)
public
view
returns(uint256)
{
uint256 supply = I_Token(msg.sender).totalSupply();
uint256 newSupply = supply.sub(_tokens);
uint256 a;
uint256 b;
uint256 c;
(a, b, c) = I_Token(msg.sender).getCurve();
return _getPrice(a, b, c, newSupply, supply);
}
function getEndPrice(
uint256 _a,
uint256 _b,
uint256 _c,
uint256 _threshold
)
public
pure
returns(uint256)
{
uint256 priceAtEnd = _getPrice(_a, _b, _c, _threshold, _threshold.add(1));
return priceAtEnd;
}
function getEndCollateral(
uint256 _a,
uint256 _b,
uint256 _c,
uint256 _threshold
)
public
pure
returns(uint256)
{
uint256 collateralAtEnd = _getPrice(_a, _b, _c, 0, _threshold);
return collateralAtEnd;
}
function _getPrice(
uint256 _a,
uint256 _b,
uint256 _c,
uint256 _from,
uint256 _to
)
internal
pure
returns(uint256)
{
uint aPrice = 0;
if(_a != 0) {
aPrice = ((_a.div(3)).mul((_to**3).sub(_from**3))).div(1e18);
}
uint256 price = aPrice + (_b.div(2)).mul(
(_to**2).sub(_from**2)
) + _c.mul(
_to.sub(_from)
);
return price.div(1e18);
}
}