11pragma solidity ^ 0.5.7 ;
22
3- import "openzeppelin-eth /contracts/token/ERC20/IERC20.sol " ;
4- import "openzeppelin-eth /contracts/math/SafeMath.sol " ;
5- import "openzeppelin-eth /contracts/ownership/Ownable.sol " ;
6- import "zos-lib /contracts/Initializable.sol " ;
3+ import "@ openzeppelin/contracts-ethereum-package /contracts/token/ERC20/IERC20.sol " ;
4+ import "@ openzeppelin/contracts-ethereum-package /contracts/math/SafeMath.sol " ;
5+ import "@ openzeppelin/contracts-ethereum-package /contracts/ownership/Ownable.sol " ;
6+ import "@openzeppelin/upgrades /contracts/Initializable.sol " ;
77import "./interface/ICurveLogic.sol " ;
88import "./dividend/DividendPool.sol " ;
99import "./token/BondedToken.sol " ;
@@ -42,13 +42,28 @@ contract BondingCurve is Initializable, Ownable {
4242 string internal constant NO_MICRO_PAYMENTS = "Payment amount must be greater than 100 'units' for calculations to work correctly " ;
4343 string internal constant TOKEN_BURN_FAILED = "bondedToken burn failed " ;
4444 string internal constant TRANSFER_TO_RECIPIENT_FAILED = "Transfer to recipient failed " ;
45-
4645
4746 event BeneficiarySet (address beneficiary );
48-
49- event Buy (address indexed buyer , address indexed recipient , uint256 amount , uint256 price , uint256 reserveAmount , uint256 beneficiaryAmount );
47+ event BuyCurveSet (address buyCurve );
48+ event SellCurveSet (address sellCurve );
49+ event SplitOnPaySet (uint256 splitOnPay );
50+
51+ event Buy (
52+ address indexed buyer ,
53+ address indexed recipient ,
54+ uint256 amount ,
55+ uint256 price ,
56+ uint256 reserveAmount ,
57+ uint256 beneficiaryAmount
58+ );
5059 event Sell (address indexed seller , address indexed recipient , uint256 amount , uint256 reward );
51- event Pay (address indexed from , address indexed token , uint256 amount , uint256 beneficiaryAmount , uint256 dividendAmount );
60+ event Pay (
61+ address indexed from ,
62+ address indexed token ,
63+ uint256 amount ,
64+ uint256 beneficiaryAmount ,
65+ uint256 dividendAmount
66+ );
5267
5368 /// @dev Initialize contract
5469 /// @param owner Contract owner, can conduct administrative functions.
@@ -69,7 +84,7 @@ contract BondingCurve is Initializable, Ownable {
6984 DividendPool dividendPool ,
7085 uint256 splitOnPay
7186 ) public initializer {
72- require (splitOnPay >= 0 && splitOnPay <= MAX_PERCENTAGE , SPLIT_ON_PAY_INVALID);
87+ require (splitOnPay <= 100 , SPLIT_ON_PAY_INVALID);
7388
7489 Ownable.initialize (owner);
7590
@@ -83,6 +98,12 @@ contract BondingCurve is Initializable, Ownable {
8398 _dividendPool = dividendPool;
8499
85100 _splitOnPay = splitOnPay;
101+
102+ emit BuyCurveSet (address (_buyCurve));
103+ emit SellCurveSet (address (_sellCurve));
104+ emit SplitOnPaySet (_splitOnPay);
105+ emit SplitOnPaySet (splitOnPay);
106+
86107 }
87108
88109 /// @notice Get the price in ether to mint tokens
@@ -101,8 +122,7 @@ contract BondingCurve is Initializable, Ownable {
101122 /// @param numTokens The number of bondedTokens to buy
102123 /// @param maxPrice Maximum total price allowable to pay in collateralTokens. If zero, any price is allowed.
103124 /// @param recipient Address to send the new bondedTokens to
104- function buy (uint256 numTokens , uint256 maxPrice , address recipient )
105- public {
125+ function buy (uint256 numTokens , uint256 maxPrice , address recipient ) public {
106126 require (numTokens > 0 , REQUIRE_NON_ZERO_NUM_TOKENS);
107127
108128 uint256 buyPrice = priceToBuy (numTokens);
@@ -120,17 +140,13 @@ contract BondingCurve is Initializable, Ownable {
120140
121141 _reserveBalance = _reserveBalance.add (tokensToReserve);
122142
123- require ( _bondedToken.mint (recipient, numTokens), TOKEN_MINTING_FAILED );
143+ _bondedToken.mint (recipient, numTokens);
124144
125145 require (
126146 _collateralToken.transferFrom (msg .sender , address (this ), buyPrice),
127147 TRANSFER_FROM_FAILED
128148 );
129-
130- require (
131- _collateralToken.transfer (_beneficiary, tokensToBeneficiary),
132- TRANSFER_TO_BENEFICIARY_FAILED
133- );
149+ _collateralToken.transfer (_beneficiary, tokensToBeneficiary);
134150
135151 emit Buy (msg .sender , recipient, numTokens, buyPrice, tokensToReserve, tokensToBeneficiary);
136152 }
@@ -139,9 +155,7 @@ contract BondingCurve is Initializable, Ownable {
139155 /// @param numTokens The number of bondedTokens to sell
140156 /// @param minPrice Minimum total price allowable to receive in collateralTokens
141157 /// @param recipient Address to send collateralTokens to
142- function sell (uint256 numTokens , uint256 minPrice , address recipient )
143- public {
144-
158+ function sell (uint256 numTokens , uint256 minPrice , address recipient ) public {
145159 require (numTokens > 0 , REQUIRE_NON_ZERO_NUM_TOKENS);
146160 require (_bondedToken.balanceOf (msg .sender ) >= numTokens, INSUFFICENT_TOKENS);
147161
@@ -151,7 +165,7 @@ contract BondingCurve is Initializable, Ownable {
151165 _reserveBalance = _reserveBalance.sub (burnReward);
152166
153167 _bondedToken.burn (msg .sender , numTokens);
154- require ( _collateralToken.transfer (recipient, burnReward), TRANSFER_TO_RECIPIENT_FAILED );
168+ _collateralToken.transfer (recipient, burnReward);
155169
156170 emit Sell (msg .sender , recipient, numTokens, burnReward);
157171 }
@@ -162,35 +176,30 @@ contract BondingCurve is Initializable, Ownable {
162176 function pay (uint256 amount ) public {
163177 require (amount > MICRO_PAYMENT_THRESHOLD, NO_MICRO_PAYMENTS);
164178
165- //TODO: Get payment token from dividendPool
166179 IERC20 paymentToken = _collateralToken;
167180
168181 uint256 tokensToBeneficiary;
169182 uint256 tokensToDividendHolders;
183+ uint256 remainderTokens;
170184
171- // Calculate amounts to beneficiary and dividend holders based on splitOnPay
172- if (_splitOnPay == 0 ) {
173- tokensToDividendHolders = amount;
174- } else if (_splitOnPay == MAX_PERCENTAGE) {
175- tokensToBeneficiary = amount;
176- } else {
177- uint256 dividendPercentage = MAX_PERCENTAGE.sub (_splitOnPay);
178-
179- tokensToBeneficiary = (amount.mul (_splitOnPay)).div (MAX_PERCENTAGE);
180- tokensToDividendHolders = (amount.mul (dividendPercentage)).div (MAX_PERCENTAGE);
181- }
182-
183- // require(tokensToBeneficiary.add(tokensToDividendHolders) <= amount, SPLIT_ON_PAY_MATH_ERROR);
185+ uint256 dividendPercentage = MAX_PERCENTAGE.sub (_splitOnPay);
184186
185- // uint256 remainderTokens = amount.sub(tokensToBeneficiary).sub(tokensToDividendHolders);
187+ tokensToBeneficiary = (amount.mul (_splitOnPay)).div (MAX_PERCENTAGE);
188+ tokensToDividendHolders = (amount.mul (dividendPercentage)).div (MAX_PERCENTAGE);
189+ remainderTokens = amount.sub (tokensToBeneficiary).sub (tokensToDividendHolders);
186190
187191 require (paymentToken.transferFrom (msg .sender , address (this ), amount), TRANSFER_FROM_FAILED);
188192
189- require (paymentToken.transfer (_beneficiary, tokensToBeneficiary), "Transfer to beneficiary failed " );
190- require (paymentToken.transfer (address (_dividendPool), tokensToDividendHolders), "Transfer to dividend pool failed " );
191- // require(paymentToken.transfer(msg.sender, remainderTokens), "Transfer of remainder to sender failed");
193+ paymentToken.transfer (_beneficiary, tokensToBeneficiary);
194+ paymentToken.transfer (address (_dividendPool), tokensToDividendHolders.add (remainderTokens));
192195
193- emit Pay (msg .sender , address (paymentToken), amount, tokensToBeneficiary, tokensToDividendHolders);
196+ emit Pay (
197+ msg .sender ,
198+ address (paymentToken),
199+ amount,
200+ tokensToBeneficiary,
201+ tokensToDividendHolders
202+ );
194203 }
195204
196205 /*
@@ -204,6 +213,27 @@ contract BondingCurve is Initializable, Ownable {
204213 emit BeneficiarySet (_beneficiary);
205214 }
206215
216+ /// @notice Set buy curve to a new address
217+ /// @param buyCurve New buy curve
218+ function setBuyCurve (ICurveLogic buyCurve ) public onlyOwner {
219+ _buyCurve = buyCurve;
220+ emit BuyCurveSet (address (_buyCurve));
221+ }
222+
223+ /// @notice Set sell curve to a new address
224+ /// @param sellCurve New sell curve
225+ function setSellCurve (ICurveLogic sellCurve ) public onlyOwner {
226+ _sellCurve = sellCurve;
227+ emit SellCurveSet (address (_sellCurve));
228+ }
229+
230+ /// @notice Set split on pay to new value
231+ /// @param splitOnPay New split on pay value
232+ function setSplitOnPay (uint256 splitOnPay ) public onlyOwner {
233+ _splitOnPay = splitOnPay;
234+ emit SplitOnPaySet (_splitOnPay);
235+ }
236+
207237 /*
208238 Getter Functions
209239 */
0 commit comments