-
Notifications
You must be signed in to change notification settings - Fork 1
/
LendingCurve.sol
91 lines (74 loc) · 2.42 KB
/
LendingCurve.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
pragma solidity ^0.5.0;
import "zos-lib/contracts/Initializable.sol";
import "./BondingCurve.sol";
contract LendingCurve is Initializable, BondingCurve {
address payable wallet;
// Desired Curve: Linear Progression W/ % Buy/Sell Delta
// Ex: Sell is always 90% of buy price.
// https://www.desmos.com/calculator/9ierxx6kjw
uint256 slopeNumerator;
uint256 slopeDenominator;
uint256 sellPercentage; // ex: 90 == 90% of buy price
event Payout(uint256 payout, uint256 indexed timestamp);
function initialize(
string memory name,
string memory symbol,
uint8 decimals,
address payable _wallet,
uint256 _slopeNumerator,
uint256 _slopeDenominator,
uint256 _sellPercentage
) public initializer {
require(
_sellPercentage < 100 && _sellPercentage != 0,
"Percentage must be between 0 & 100"
);
BondingCurve.initialize(name, symbol, decimals);
wallet = _wallet;
slopeNumerator = _slopeNumerator;
slopeDenominator = _slopeDenominator;
sellPercentage = _sellPercentage;
}
function buyIntegral(uint256 x)
internal view returns (uint256)
{
return (slopeNumerator * x * x) / (2 * slopeDenominator);
}
function sellIntegral(uint256 x)
internal view returns (uint256)
{
return (slopeNumerator * x * x * sellPercentage) / (200 * slopeDenominator);
}
function spread(uint256 toX)
public view returns (uint256)
{
uint256 buy = buyIntegral(toX);
uint256 sell = sellIntegral(toX);
return buy.sub(sell);
}
/// Overwrite
function buy(uint256 tokens) public payable {
uint256 spreadBefore = spread(totalSupply());
super.buy(tokens);
uint256 spreadAfter = spread(totalSupply());
uint256 spreadPayout = spreadAfter.sub(spreadBefore);
reserve = reserve.sub(spreadPayout);
wallet.transfer(spreadPayout);
emit Payout(spreadPayout, now);
}
function calculatePurchaseReturn(uint256 tokens)
public view returns (uint256)
{
return buyIntegral(
totalSupply().add(tokens)
).sub(reserve);
}
function calculateSaleReturn(uint256 tokens)
public view returns (uint256)
{
return reserve.sub(
sellIntegral(
totalSupply().sub(tokens)
));
}
}