Advertisement
Guest User

Untitled

a guest
Feb 28th, 2020
1,018
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 27.91 KB | None | 0 0
  1. pragma solidity ^ 0.6.3;
  2. /*
  3. ,/`.
  4. ,'/ __`.
  5. ,'_/__ _ _`.
  6. ,'__/__ _ _ _`.
  7. ,'_ /___ __ _ __ `.
  8. '-.._/___ _ __ __ __`.
  9.  
  10. */
  11. contract Pyramid{
  12. // scaleFactor is used to convert Ether into bonds and vice-versa: they're of different
  13. // orders of magnitude, hence the need to bridge between the two.
  14. uint256 constant scaleFactor = 0x10000000000000000;
  15. address payable address0 = address(0);
  16.  
  17. int constant crr_n = 1;
  18. int constant crr_d = 2;
  19.  
  20. int constant public slope = -0x1337FA66607BADA55;
  21.  
  22. // Typical values that we have to declare.
  23. string constant public name = "Mass";
  24. string constant public symbol = "Mass";
  25. uint8 constant public decimals = 18;
  26.  
  27.  
  28. // Array between each address and their number of bonds.
  29. mapping(address => uint256) public mass;
  30. mapping(address => mapping(address => uint)) approvals;
  31. // For calculating resolves minted
  32. mapping(address => uint256) public average_ethSpent;
  33. // For calculating hodl multiplier that factors into resolves minted
  34. mapping(address => uint256) public average_buyInTimeSum;
  35. // Array between each address and their number of resolves being staked.
  36. mapping(address => uint256) public resolveWeight;
  37.  
  38. // Array between each address and how much Ether has been paid out to it.
  39. // Note that this is scaled by the scaleFactor variable.
  40. mapping(address => int256) public payouts;
  41.  
  42. // Variable tracking how many bonds are in existence overall.
  43. uint256 public _totalSupply;
  44.  
  45. // The total number of resolves being staked in this contract
  46. uint256 public dissolvingResolves;
  47.  
  48. // The ethereum locked up into bonds
  49. uint public contractBalance;
  50.  
  51. // For calculating the hodl multiplier. Weighted average release time
  52. uint public sumOfInputETH;
  53. uint public sumOfInputTime;
  54. uint public sumOfOutputETH;
  55. uint public sumOfOutputTime;
  56.  
  57. // Something about invarience.
  58. int256 earningsOffset;
  59.  
  60. // Variable tracking how much Ether each token is currently worth.
  61. // Note that this is scaled by the scaleFactor variable.
  62. uint256 earningsPerResolve;
  63.  
  64. //The resolve token contract
  65. ResolveToken public resolveToken;
  66.  
  67. constructor() public{
  68. resolveToken = new ResolveToken( address(this) );
  69. }
  70.  
  71. function totalSupply() public view returns (uint256) {
  72. return _totalSupply;
  73. }
  74.  
  75. // Returns the number of bonds currently held by _owner.
  76. function balanceOf(address _owner) public view returns (uint256 balance) {
  77. return mass[_owner];
  78. }
  79.  
  80. function fluxFee(uint paidAmount) public view returns (uint fee) {
  81. uint totalResolveSupply = resolveToken.totalSupply() - resolveToken.balanceOf( address(0) );
  82. if ( dissolvingResolves == 0 )
  83. return 0;
  84.  
  85. return paidAmount * ( totalResolveSupply - dissolvingResolves ) / totalResolveSupply * sumOfOutputETH / sumOfInputETH;
  86. }
  87.  
  88. // Converts the Ether accrued as resolveEarnings back into bonds without having to
  89. // withdraw it first. Saves on gas and potential price spike loss.
  90. event Reinvest( address indexed addr, uint256 reinvested, uint256 dissolved, uint256 bonds, uint256 resolveTax);
  91. function reinvestEarnings(uint amountFromEarnings) public returns(uint,uint){
  92. address sender = msg.sender;
  93. // Retrieve the resolveEarnings associated with the address the request came from.
  94. uint upScaleDivs = (uint)((int256)( earningsPerResolve * resolveWeight[sender] ) - payouts[sender]);
  95. uint totalEarnings = upScaleDivs / scaleFactor;//resolveEarnings(sender);
  96. require(amountFromEarnings <= totalEarnings, "the amount exceeds total earnings");
  97. uint oldWeight = resolveWeight[sender];
  98. resolveWeight[sender] = oldWeight * (totalEarnings - amountFromEarnings) / totalEarnings;
  99. uint weightDiff = oldWeight - resolveWeight[sender];
  100. resolveToken.transfer( address0, weightDiff );
  101. dissolvingResolves -= weightDiff;
  102.  
  103. // something about invariance
  104. int withdrawnEarnings = (int)(upScaleDivs * amountFromEarnings / totalEarnings) - (int)(weightDiff*earningsPerResolve);
  105. payouts[sender] += withdrawnEarnings;
  106. // Increase the total amount that's been paid out to maintain invariance.
  107. earningsOffset += withdrawnEarnings;
  108.  
  109. // Assign balance to a new variable.
  110. uint value_ = (uint) (amountFromEarnings);
  111.  
  112. // If your resolveEarnings are worth less than 1 szabo, abort.
  113. if (value_ < 0.000001 ether)
  114. revert();
  115.  
  116. // Calculate the fee
  117. uint fee = fluxFee(value_);
  118.  
  119. // The amount of Ether used to purchase new bonds for the caller
  120. uint numEther = value_ - fee;
  121.  
  122. //resolve reward tracking stuff
  123. average_ethSpent[sender] += numEther;
  124. average_buyInTimeSum[sender] += now * scaleFactor * numEther;
  125. sumOfInputETH += numEther;
  126. sumOfInputTime += now * scaleFactor * numEther;
  127.  
  128. // The number of bonds which can be purchased for numEther.
  129. uint createdBonds = calculateBondsFromReinvest(numEther, amountFromEarnings);
  130.  
  131. // the variable stoslope the amount to be paid to stakers
  132. uint resolveFee;
  133.  
  134. // Check if we have bonds in existence
  135. if ( dissolvingResolves > 0 ) {
  136. resolveFee = fee * scaleFactor;
  137.  
  138. // Fee is distributed to all existing resolve stakers before the new bonds are purchased.
  139. // rewardPerResolve is the amount(ETH) gained per resolve token from this purchase.
  140. uint rewardPerResolve = resolveFee / dissolvingResolves;
  141.  
  142. // The Ether value per token is increased proportionally.
  143. earningsPerResolve += rewardPerResolve;
  144. }
  145.  
  146. // Add the createdBonds to the total supply.
  147. _totalSupply += createdBonds;
  148.  
  149. // Assign the bonds to the balance of the buyer.
  150. mass[sender] += createdBonds;
  151.  
  152. emit Reinvest(sender, value_, weightDiff, createdBonds, resolveFee);
  153. return (createdBonds, weightDiff);
  154. }
  155.  
  156. // Sells your bonds for Ether
  157. function sellAllBonds() public returns(uint returned_eth, uint returned_resolves, uint initialInput_ETH){
  158. return sell( balanceOf(msg.sender) );
  159. }
  160. function sellBonds(uint amount) public returns(uint returned_eth, uint returned_resolves, uint initialInput_ETH){
  161. uint balance = balanceOf(msg.sender);
  162. require(balance >= amount, "Amount is more than balance");
  163. ( returned_eth, returned_resolves, initialInput_ETH ) = sell(amount);
  164. return (returned_eth, returned_resolves, initialInput_ETH);
  165. }
  166.  
  167. // Big red exit button to pull all of a holder's Ethereum value from the contract
  168. function getMeOutOfHere() public {
  169. sellAllBonds();
  170. withdraw( resolveEarnings(msg.sender) );
  171. }
  172.  
  173. // Gatekeeper function to check if the amount of Ether being sent isn't too small
  174. function fund() payable public returns(uint){
  175. uint bought;
  176. if (msg.value > 0.000001 ether) {
  177. contractBalance += msg.value;
  178. bought = buy();
  179. } else {
  180. revert();
  181. }
  182. return bought;
  183. }
  184.  
  185. // Function that returns the (dynamic) pricing for buys, sells and fee
  186. function pricing(uint scale) public view returns (uint buyPrice, uint sellPrice, uint fee) {
  187. uint buy_eth = scaleFactor * getPriceForBonds( scale, true) / ( scaleFactor - fluxFee(scaleFactor) ) ;
  188. uint sell_eth = getPriceForBonds(scale, false);
  189. sell_eth -= fluxFee(sell_eth);
  190. return ( buy_eth, sell_eth, fluxFee(scale) );
  191. }
  192.  
  193. // For calculating the price
  194. function getPriceForBonds(uint256 bonds, bool buy_or_sell) public view returns (uint256 price) {
  195. uint reserveAmount = reserve();
  196.  
  197. if(buy_or_sell){
  198. uint x = fixedExp((fixedLog(_totalSupply + bonds) - slope) * crr_d/crr_n);
  199. return x - reserveAmount;
  200. }else{
  201. uint x = fixedExp((fixedLog(_totalSupply - bonds) - slope) * crr_d/crr_n);
  202. return reserveAmount - x;
  203. }
  204. }
  205.  
  206. // Calculate the current resolveEarnings associated with the caller address. This is the net result
  207. // of multiplying the number of resolves held by their current value in Ether and subtracting the
  208. // Ether that has already been paid out.
  209. function resolveEarnings(address _owner) public view returns (uint256 amount) {
  210. return (uint256) ((int256)(earningsPerResolve * resolveWeight[_owner]) - payouts[_owner]) / scaleFactor;
  211. }
  212.  
  213. event Buy( address indexed addr, uint256 spent, uint256 bonds, uint256 resolveTax);
  214. function buy() internal returns(uint){
  215. address sender = msg.sender;
  216. // Any transaction of less than 1 szabo is likely to be worth less than the gas used to send it.
  217. if ( msg.value < 0.000001 ether )
  218. revert();
  219.  
  220. // Calculate the fee
  221. uint fee = fluxFee(msg.value);
  222.  
  223. // The amount of Ether used to purchase new bonds for the caller.
  224. uint numEther = msg.value - fee;
  225.  
  226. //resolve reward tracking stuff
  227. uint currentTime = now;
  228. average_ethSpent[sender] += numEther;
  229. average_buyInTimeSum[sender] += currentTime * scaleFactor * numEther;
  230. sumOfInputETH += numEther;
  231. sumOfInputTime += currentTime * scaleFactor * numEther;
  232.  
  233. // The number of bonds which can be purchased for numEther.
  234. uint createdBonds = getBondsForEther(numEther);
  235.  
  236. // Add the createdBonds to the total supply.
  237. _totalSupply += createdBonds;
  238.  
  239. // Assign the bonds to the balance of the buyer.
  240. mass[sender] += createdBonds;
  241.  
  242. // Check if we have bonds in existence
  243. uint resolveFee;
  244. if (dissolvingResolves > 0) {
  245. resolveFee = fee * scaleFactor;
  246.  
  247. // Fee is distributed to all existing resolve holders before the new bonds are purchased.
  248. // rewardPerResolve is the amount gained per resolve token from this purchase.
  249. uint rewardPerResolve = resolveFee/dissolvingResolves;
  250.  
  251. // The Ether value per resolve is increased proportionally.
  252. earningsPerResolve += rewardPerResolve;
  253. }
  254. emit Buy( sender, msg.value, createdBonds, resolveFee);
  255. return createdBonds;
  256. }
  257.  
  258. function avgHodl() public view returns(uint hodlTime){
  259. return now - (sumOfInputTime - sumOfOutputTime) / (sumOfInputETH - sumOfOutputETH) / scaleFactor;
  260. }
  261.  
  262. function getReturnsForBonds(address addr, uint bondsReleased) public view returns(uint etherValue, uint mintedResolves, uint new_releaseTimeSum, uint new_releaseAmount, uint initialInput_ETH){
  263. uint output_ETH = getEtherForBonds(bondsReleased);
  264. uint input_ETH = average_ethSpent[addr] * bondsReleased / mass[addr];
  265. // hodl multiplier. because if you don't hodl at all, you shouldn't be rewarded resolves.
  266. // and the multiplier you get for hodling needs to be relative to the average hodl
  267. uint buyInTime = average_buyInTimeSum[addr] / average_ethSpent[addr];
  268. uint cashoutTime = now * scaleFactor - buyInTime;
  269. uint new_sumOfOutputTime = sumOfOutputTime + average_buyInTimeSum[addr] * bondsReleased / mass[addr];
  270. uint new_sumOfOutputETH = sumOfOutputETH + input_ETH;//It's based on the original ETH, so that's why input_ETH is used. Not output_ETH.
  271. uint averageHoldingTime = now * scaleFactor - ( sumOfInputTime - sumOfOutputTime ) / ( sumOfInputETH - sumOfOutputETH );
  272. return (output_ETH, input_ETH * cashoutTime / averageHoldingTime * input_ETH / output_ETH, new_sumOfOutputTime, new_sumOfOutputETH, input_ETH);
  273. }
  274.  
  275. event Sell( address indexed addr, uint256 bondsSold, uint256 cashout, uint256 resolves, uint256 resolveTax, uint256 initialCash);
  276. function sell(uint256 amount) internal returns(uint eth, uint resolves, uint initialInput){
  277. address payable sender = msg.sender;
  278. // Calculate the amount of Ether & Resolves that the holder's bonds sell for at the current sell price.
  279. (uint numEthersBeforeFee,uint mintedResolves,uint new_sumOfOutputTime,uint new_sumOfOutputETH,uint initialInput_ETH) = getReturnsForBonds(sender, amount);
  280.  
  281. // calculate the fee
  282. uint fee = fluxFee(numEthersBeforeFee);
  283.  
  284. // magic distribution
  285. resolveToken.mint(sender, mintedResolves);
  286.  
  287. // update weighted average cashout time
  288. sumOfOutputTime = new_sumOfOutputTime;
  289. sumOfOutputETH = new_sumOfOutputETH;
  290.  
  291. // reduce the amount of "eth spent" based on the percentage of bonds being sold back into the contract
  292. average_ethSpent[sender] = average_ethSpent[sender] * ( mass[sender] - amount) / mass[sender];
  293. // reduce the "buyInTime" sum that's used for average buy in time
  294. average_buyInTimeSum[sender] = average_buyInTimeSum[sender] * (mass[sender] - amount) / mass[sender];
  295.  
  296.  
  297. // Net Ether for the seller after the fee has been subtracted.
  298. uint numEthers = numEthersBeforeFee - fee;
  299.  
  300. // Burn the bonds which were just sold from the total supply.
  301. _totalSupply -= amount;
  302.  
  303. // Remove the bonds from the balance of the buyer.
  304. mass[sender] -= amount;
  305.  
  306.  
  307. // Check if we have bonds in existence
  308. uint resolveFee;
  309. if ( dissolvingResolves > 0 ){
  310. // Scale the Ether taken as the selling fee by the scaleFactor variable.
  311. resolveFee = fee * scaleFactor;
  312.  
  313. // Fee is distributed to all remaining resolve holders.
  314. // rewardPerResolve is the amount gained per resolve thanks to this sell.
  315. uint rewardPerResolve = resolveFee/dissolvingResolves;
  316.  
  317. // The Ether value per resolve is increased proportionally.
  318. earningsPerResolve += rewardPerResolve;
  319. }
  320.  
  321. // Send the ethereum to the address that requested the sell.
  322. contractBalance -= numEthers;
  323.  
  324. (bool success, ) = sender.call.value(numEthers)("");
  325. require(success, "Transfer failed.");
  326.  
  327. emit Sell( sender, amount, numEthers, mintedResolves, resolveFee, initialInput_ETH);
  328. return (numEthers, mintedResolves, initialInput_ETH);
  329. }
  330.  
  331. // Dynamic value of Ether in reserve, according to the CRR requirement.
  332. function reserve() public view returns (uint256 amount) {
  333. return Common.subtract( balance(), (uint256) ((int256) (earningsPerResolve * dissolvingResolves) - earningsOffset) / scaleFactor );
  334. }
  335. function balance() internal view returns (uint256 amount) {
  336. // msg.value is the amount of Ether sent by the transaction.
  337. return contractBalance - msg.value;
  338. }
  339.  
  340. // Calculates the number of bonds that can be bought for a given amount of Ether, according to the
  341. // dynamic reserve and _totalSupply values (derived from the buy and sell prices).
  342. function getBondsForEther(uint256 ethervalue) public view returns (uint256 bonds) {
  343. return Common.subtract(fixedExp( fixedLog( reserve() + ethervalue ) * crr_n/crr_d + slope ) , _totalSupply);
  344. }
  345.  
  346. // Semantically similar to getBondsForEther, but subtracts the callers balance from the amount of Ether returned for conversion.
  347. function calculateBondsFromReinvest(uint256 ethervalue, uint256 subvalue) public view returns (uint256 bondTokens) {
  348. return Common.subtract(fixedExp(fixedLog(Common.subtract(reserve() , subvalue) + ethervalue)*crr_n/crr_d + slope) , _totalSupply);
  349. }
  350.  
  351. // Converts a number bonds into an Ether value.
  352. function getEtherForBonds(uint256 bondTokens) public view returns (uint256 ethervalue) {
  353. // How much reserve Ether do we have left in the contract?
  354. uint reserveAmount = reserve();
  355.  
  356. // If you're the Highlander (or bagholder), you get The Prize. Everything left in the remainder's vault.
  357. if (bondTokens == _totalSupply)
  358. return reserveAmount;
  359.  
  360. // If there would be excess Ether left after the transaction this is called within, return the Ether
  361. // corresponding to the equation in Dr Jochen Hoenicke's original Ponzi paper, which can be found
  362. // at https://test.jochen-hoenicke.de/eth/ponzitoken/ in the third equation, with the CRR numerator
  363. // and denominator altered to 1 and 2 respectively.
  364. return Common.subtract(reserveAmount, fixedExp( ( fixedLog(_totalSupply-bondTokens)-slope ) * crr_d/crr_n) );
  365. }
  366.  
  367. // You don't care about these, but if you really do they're hex values for
  368. // co-efficients used to simulate approximations of the log and exp functions.
  369. int256 constant one = 0x10000000000000000;
  370. uint256 constant sqrt2 = 0x16a09e667f3bcc908;
  371. uint256 constant sqrtdot5 = 0x0b504f333f9de6484;
  372. int256 constant ln2 = 0x0b17217f7d1cf79ac;
  373. int256 constant ln2_64dot5 = 0x2cb53f09f05cc627c8;
  374. int256 constant c1 = 0x1ffffffffff9dac9b;
  375. int256 constant c3 = 0x0aaaaaaac16877908;
  376. int256 constant c5 = 0x0666664e5e9fa0c99;
  377. int256 constant c7 = 0x049254026a7630acf;
  378. int256 constant c9 = 0x038bd75ed37753d68;
  379. int256 constant c11 = 0x03284a0c14610924f;
  380.  
  381. // The polynomial R = c1*x + c3*x^3 + ... + c11 * x^11
  382. // approximates the function log(1+x)-log(1-x)
  383. // Hence R(s) = log((1+s)/(1-s)) = log(a)
  384. function fixedLog(uint256 a) internal pure returns (int256 log) {
  385. int32 scale = 0;
  386. while (a > sqrt2) {
  387. a /= 2;
  388. scale++;
  389. }
  390. while (a <= sqrtdot5) {
  391. a *= 2;
  392. scale--;
  393. }
  394. int256 s = (((int256)(a) - one) * one) / ((int256)(a) + one);
  395. int z = (s*s) / one;
  396. return scale * ln2 +
  397. (s*(c1 + (z*(c3 + (z*(c5 + (z*(c7 + (z*(c9 + (z*c11/one))
  398. /one))/one))/one))/one))/one);
  399. }
  400.  
  401. int256 constant c2 = 0x02aaaaaaaaa015db0;
  402. int256 constant c4 = -0x000b60b60808399d1;
  403. int256 constant c6 = 0x0000455956bccdd06;
  404. int256 constant c8 = -0x000001b893ad04b3a;
  405.  
  406. // The polynomial R = 2 + c2*x^2 + c4*x^4 + ...
  407. // approximates the function x*(exp(x)+1)/(exp(x)-1)
  408. // Hence exp(x) = (R(x)+x)/(R(x)-x)
  409. function fixedExp(int256 a) internal pure returns (uint256 exp) {
  410. int256 scale = (a + (ln2_64dot5)) / ln2 - 64;
  411. a -= scale*ln2;
  412. int256 z = (a*a) / one;
  413. int256 R = ((int256)(2) * one) +
  414. (z*(c2 + (z*(c4 + (z*(c6 + (z*c8/one))/one))/one))/one);
  415. exp = (uint256) (((R + a) * one) / (R - a));
  416. if (scale >= 0)
  417. exp <<= scale;
  418. else
  419. exp >>= -scale;
  420. return exp;
  421. }
  422.  
  423. // Allow contract to accept resolve tokens
  424. event StakeResolves( address indexed addr, uint256 amountStaked, bytes _data );
  425. function tokenFallback(address from, uint value, bytes calldata _data) external{
  426. if(msg.sender == address(resolveToken) ){
  427. resolveWeight[from] += value;
  428. dissolvingResolves += value;
  429.  
  430. // Then we update the payouts array for the "resolve shareholder" with this amount
  431. int payoutDiff = (int256) (earningsPerResolve * value);
  432. payouts[from] += payoutDiff;
  433. earningsOffset += payoutDiff;
  434.  
  435. emit StakeResolves(from, value, _data);
  436. }else{
  437. revert("no want");
  438. }
  439. }
  440.  
  441.  
  442. // Withdraws resolveEarnings held by the caller sending the transaction, updates
  443. // the requisite global variables, and transfers Ether back to the caller.
  444. event Withdraw( address indexed addr, uint256 earnings, uint256 dissolve );
  445. function withdraw(uint amount) public returns(uint){
  446. address payable sender = msg.sender;
  447. // Retrieve the resolveEarnings associated with the address the request came from.
  448. uint upScaleDivs = (uint)((int256)( earningsPerResolve * resolveWeight[sender] ) - payouts[sender]);
  449. uint totalEarnings = upScaleDivs / scaleFactor;
  450. require( amount <= totalEarnings && amount > 0 );
  451. uint oldWeight = resolveWeight[sender];
  452. resolveWeight[sender] = oldWeight * ( totalEarnings - amount ) / totalEarnings;
  453. uint weightDiff = oldWeight - resolveWeight[sender];
  454. resolveToken.transfer( address0, weightDiff);
  455. dissolvingResolves -= weightDiff;
  456.  
  457. // something about invariance
  458. int withdrawnEarnings = (int)(upScaleDivs * amount / totalEarnings) - (int)(weightDiff*earningsPerResolve);
  459. payouts[sender] += withdrawnEarnings;
  460. // Increase the total amount that's been paid out to maintain invariance.
  461. earningsOffset += withdrawnEarnings;
  462.  
  463. contractBalance -= amount;
  464.  
  465. // Send the resolveEarnings to the address that requested the withdraw.
  466. (bool success, ) = sender.call.value(amount)("");
  467. require(success, "Transfer failed.");
  468.  
  469. emit Withdraw( sender, amount, weightDiff);
  470. return weightDiff;
  471. }
  472. event PullResolves( address indexed addr, uint256 pulledResolves, uint256 forfeiture);
  473. function pullResolves(uint amount) public returns (uint forfeiture){
  474. address sender = msg.sender;
  475. uint resolves = resolveWeight[ sender ];
  476. require(amount <= resolves && amount > 0);
  477. require(amount < dissolvingResolves);//"you can't forfeit the last resolve"
  478.  
  479. uint yourTotalEarnings = (uint)((int256)(resolves * earningsPerResolve) - payouts[sender]);
  480. uint forfeitedEarnings = yourTotalEarnings * amount / resolves;
  481.  
  482. // Update the payout array so that the "resolve shareholder" cannot claim resolveEarnings on previous staked resolves.
  483. payouts[sender] += (int256)(forfeitedEarnings) - (int256)(earningsPerResolve * amount);
  484.  
  485. resolveWeight[sender] -= amount;
  486. dissolvingResolves -= amount;
  487. // The Ether value per token is increased proportionally.
  488. earningsPerResolve += forfeitedEarnings / dissolvingResolves;
  489.  
  490. resolveToken.transfer( sender, amount );
  491. emit PullResolves( sender, amount, forfeitedEarnings / scaleFactor);
  492. return forfeitedEarnings / scaleFactor;
  493. }
  494.  
  495. // Function that is called when a user or another contract wants to transfer funds .
  496. function transfer(address _to, uint _value, bytes memory _data) public returns (bool success) {
  497. if (balanceOf(msg.sender) < _value) revert();
  498. if(Common.isContract(_to)) {
  499. return transferToContract(_to, _value, _data);
  500. }else{
  501. return transferToAddress(_to, _value, _data);
  502. }
  503. }
  504.  
  505. // Standard function transfer similar to ERC20 transfer with no _data .
  506. // Added due to backwards compatibility reasons .
  507. function transfer(address _to, uint _value) public returns (bool success) {
  508. if (balanceOf(msg.sender) < _value) revert();
  509. //standard function transfer similar to ERC20 transfer with no _data
  510. //added due to backwards compatibility reasons
  511. bytes memory empty;
  512. if(Common.isContract(_to)){
  513. return transferToContract(_to, _value, empty);
  514. }else{
  515. return transferToAddress(_to, _value, empty);
  516. }
  517. }
  518.  
  519. //function that is called when transaction target is an address
  520. function transferToAddress(address _to, uint _value, bytes memory _data) private returns (bool success) {
  521. moveTokens(msg.sender,_to,_value);
  522. emit Transfer(msg.sender, _to, _value, _data);
  523. return true;
  524. }
  525.  
  526. //function that is called when transaction target is a contract
  527. function transferToContract(address _to, uint _value, bytes memory _data) private returns (bool success) {
  528. address sender = msg.sender;
  529. moveTokens(sender, _to, _value);
  530. ERC223ReceivingContract reciever = ERC223ReceivingContract(_to);
  531. reciever.tokenFallback(sender, _value, _data);
  532. emit Transfer(sender, _to, _value, _data);
  533. return true;
  534. }
  535.  
  536. function moveTokens(address _from, address _to, uint _amount) private{
  537.  
  538. uint totalBonds = mass[_from];
  539. require(_amount <= totalBonds && _amount > 0);
  540. uint ethSpent = average_ethSpent[_from] * _amount / totalBonds;
  541. uint buyInTimeSum = average_buyInTimeSum[_from] * _amount / totalBonds;
  542. average_ethSpent[_from] -= ethSpent;
  543. average_buyInTimeSum[_from] -= buyInTimeSum;
  544. mass[_from] -= _amount;
  545. average_ethSpent[_to] += ethSpent;
  546. average_buyInTimeSum[_to] += buyInTimeSum;
  547. mass[_to] += _amount;
  548. }
  549.  
  550. function allowance(address src, address guy) public view returns (uint) {
  551. return approvals[src][guy];
  552. }
  553.  
  554. function transferFrom(address src, address dst, uint wad) public returns (bool){
  555. address sender = msg.sender;
  556. require(approvals[src][sender] >= wad, "That amount is not approved");
  557. require(mass[src] >= wad, "That amount is not available from this wallet");
  558. if (src != sender) {
  559. approvals[src][sender] -= wad;
  560. }
  561. moveTokens(src,dst,wad);
  562.  
  563. bytes memory empty;
  564. emit Transfer(src, dst, wad, empty);
  565.  
  566. return true;
  567. }
  568.  
  569. function approve(address guy, uint wad) public returns (bool) {
  570. approvals[msg.sender][guy] = wad;
  571.  
  572. emit Approval(msg.sender, guy, wad);
  573.  
  574. return true;
  575. }
  576. event Transfer(
  577. address indexed from,
  578. address indexed to,
  579. uint256 amount,
  580. bytes data
  581. );
  582. event Approval(address indexed src, address indexed guy, uint wad);
  583. }
  584.  
  585. abstract contract ERC223ReceivingContract{
  586. function tokenFallback(address _from, uint _value, bytes calldata _data) external virtual;
  587. }
  588.  
  589. contract ResolveToken{
  590.  
  591.  
  592. mapping(address => uint) balances;
  593. mapping(address => mapping(address => uint)) approvals;
  594.  
  595. string public name = "Resolve";
  596. string public symbol = "`r";
  597. uint8 constant public decimals = 18;
  598. uint256 private _totalSupply;
  599. address public hourglass;
  600.  
  601. constructor(address _hourglass) public{
  602. hourglass = _hourglass;
  603. }
  604.  
  605. modifier hourglassOnly{
  606. require(msg.sender == hourglass);
  607. _;
  608. }
  609.  
  610. event Transfer(
  611. address indexed from,
  612. address indexed to,
  613. uint256 amount,
  614. bytes data
  615. );
  616.  
  617. event Mint(
  618. address indexed addr,
  619. uint256 amount
  620. );
  621.  
  622. function totalSupply() public view returns (uint256) {
  623. return _totalSupply;
  624. }
  625.  
  626. function mint(address _address, uint _value) external hourglassOnly(){
  627. balances[_address] += _value;
  628. _totalSupply += _value;
  629. emit Mint(_address, _value);
  630. }
  631.  
  632. // Function that is called when a user or another contract wants to transfer funds .
  633. function transfer(address _to, uint _value, bytes memory _data) public returns (bool success) {
  634. if (balanceOf(msg.sender) < _value) revert();
  635. if(Common.isContract(_to)) {
  636. return transferToContract(_to, _value, _data);
  637. }else{
  638. return transferToAddress(_to, _value, _data);
  639. }
  640. }
  641.  
  642. // Standard function transfer similar to ERC20 transfer with no _data .
  643. // Added due to backwards compatibility reasons .
  644. function transfer(address _to, uint _value) public returns (bool success) {
  645. if (balanceOf(msg.sender) < _value) revert();
  646. //standard function transfer similar to ERC20 transfer with no _data
  647. //added due to backwards compatibility reasons
  648. bytes memory empty;
  649. if(Common.isContract(_to)){
  650. return transferToContract(_to, _value, empty);
  651. }else{
  652. return transferToAddress(_to, _value, empty);
  653. }
  654. }
  655.  
  656. //function that is called when transaction target is an address
  657. function transferToAddress(address _to, uint _value, bytes memory _data) private returns (bool success) {
  658. moveTokens(msg.sender,_to,_value);
  659. emit Transfer(msg.sender, _to, _value, _data);
  660. return true;
  661. }
  662.  
  663. //function that is called when transaction target is a contract
  664. function transferToContract(address _to, uint _value, bytes memory _data) private returns (bool success) {
  665. address sender = msg.sender;
  666. moveTokens(sender, _to, _value);
  667. ERC223ReceivingContract reciever = ERC223ReceivingContract(_to);
  668. reciever.tokenFallback(sender, _value, _data);
  669. emit Transfer(sender, _to, _value, _data);
  670. return true;
  671. }
  672.  
  673. function moveTokens(address _from, address _to, uint _amount) private{
  674. balances[_from] -= _amount;
  675. balances[_to] += _amount;
  676. }
  677.  
  678. function balanceOf(address _owner) public view returns (uint balance) {
  679. return balances[_owner];
  680. }
  681.  
  682. function allowance(address src, address guy) public view returns (uint) {
  683. return approvals[src][guy];
  684. }
  685.  
  686. function transferFrom(address src, address dst, uint wad) public returns (bool){
  687. address sender = msg.sender;
  688. require(approvals[src][sender] >= wad, "That amount is not approved");
  689. require(balances[src] >= wad, "That amount is not available from this wallet");
  690. if (src != sender) {
  691. approvals[src][sender] -= wad;
  692. }
  693. moveTokens(src,dst,wad);
  694.  
  695. bytes memory empty;
  696. emit Transfer(src, dst, wad, empty);
  697.  
  698. return true;
  699. }
  700.  
  701. function approve(address guy, uint wad) public returns (bool) {
  702. approvals[msg.sender][guy] = wad;
  703.  
  704. emit Approval(msg.sender, guy, wad);
  705.  
  706. return true;
  707. }
  708.  
  709. event Approval(address indexed src, address indexed guy, uint wad);
  710. }
  711.  
  712. /**
  713. * @title Common
  714. * @dev Math operations with safety checks that throw on error
  715. */
  716. library Common {
  717. /**
  718. * @dev Substracts two numbers, throws on overflow (i.e. if subtrahend is greater than minuend).
  719. */
  720. function subtract(uint256 a, uint256 b) internal pure returns (uint256) {
  721. assert(b <= a);
  722. return a - b;
  723. }
  724.  
  725. //assemble the given address bytecode. If bytecode exists then the _addr is a contract.
  726. function isContract(address _addr) public view returns (bool is_contract) {
  727. uint length;
  728. assembly {
  729. //retrieve the size of the code on target address, this needs assembly
  730. length := extcodesize(_addr)
  731. }
  732. if(length>0) {
  733. return true;
  734. }else {
  735. return false;
  736. }
  737. }
  738. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement