From f15693af1d13c06492d0a32464f4fe65865ff461 Mon Sep 17 00:00:00 2001 From: Greg Hysen Date: Thu, 23 May 2019 17:26:04 -0700 Subject: [PATCH] Much simplified cobb douglas implementation --- .../staking/contracts/src/libs/LibMath.sol | 45 +++++++++++++------ contracts/staking/test/core_test.ts | 18 +++----- 2 files changed, 39 insertions(+), 24 deletions(-) diff --git a/contracts/staking/contracts/src/libs/LibMath.sol b/contracts/staking/contracts/src/libs/LibMath.sol index 356549bcb0..2637447d43 100644 --- a/contracts/staking/contracts/src/libs/LibMath.sol +++ b/contracts/staking/contracts/src/libs/LibMath.sol @@ -136,8 +136,35 @@ library LibMath { return result; } + function _exp2(uint256 numerator_1, uint256 numerator_2, uint256 denominator, uint256 power) + internal + pure + returns (uint256 result) + { + result = (numerator_1 * numerator_2) / denominator; + for(power = power - 1; power > 0; power -= 1) { + result *= numerator_1; + result /= denominator; + result *= numerator_2; + } + return result; + } + + function _exp3(uint256 numerator, uint256 denominator, uint256 power) + internal + pure + returns (uint256 result) + { + result = numerator / denominator; + for(power = power - 1; power > 0; power -= 1) { + result = (result * numerator) / denominator; + } + return result; + } + uint256 constant fixedPointDecimals = 18; uint256 constant scalar = 10**fixedPointDecimals; + uint256 constant halfScalar = 10**(fixedPointDecimals/2); // rough implementation of cobb-douglas using the nth root fixed point algorithm above function _cobbDouglas( @@ -153,18 +180,10 @@ library LibMath { pure returns (uint256) { - require( - alphaDenominator - alphaNumerator <= 10, - "numerator of (1 - alpha) is out of range" - ); - - uint256 feeRatio = _exp((totalRewards * ownerFees) / totalFees, alphaNumerator); - uint256 rootedFeeRatio = _nthRootFixedPoint(feeRatio, alphaDenominator, fixedPointDecimals); - - uint256 inverseAlphaNumerator = alphaDenominator - alphaNumerator; - uint256 stakeRatio = _exp((totalRewards * ownerStake) / totalStake, inverseAlphaNumerator); - uint256 rootedStakeRatio = _nthRootFixedPoint(stakeRatio, alphaDenominator, fixedPointDecimals); - - return (rootedFeeRatio * rootedStakeRatio) / scalar; + uint256 lhs = _exp3(_nthRootFixedPoint(ownerFees * totalStake, alphaDenominator, 18), + _nthRootFixedPoint(totalFees * ownerStake, alphaDenominator, 18), + alphaNumerator + ); + return lhs * ((totalRewards * ownerStake) / totalStake); } } diff --git a/contracts/staking/test/core_test.ts b/contracts/staking/test/core_test.ts index 7846844417..d3d4bab3b0 100644 --- a/contracts/staking/test/core_test.ts +++ b/contracts/staking/test/core_test.ts @@ -210,12 +210,13 @@ describe('Staking Core', () => { const alphaNumerator = new BigNumber(1); const alphaDenominator = new BigNumber(2); - /*const expectedOwnerReward = totalRewards + const expectedOwnerReward = totalRewards .times( (ownerFees.div(totalFees)).squareRoot() ).times( (ownerStake.div(totalStake)).squareRoot() ).dividedToIntegerBy(1); // 25000000000000000000*/ + console.log(`EXPECTED - `, stakingWrapper.toFloatingPoint(expectedOwnerReward, 18)); const ownerReward = await stakingWrapper.cobbDouglas( totalRewards, @@ -226,8 +227,7 @@ describe('Staking Core', () => { alphaNumerator, alphaDenominator ); - console.log(ownerReward); - console.log(stakingWrapper.toFloatingPoint(ownerReward, 18)); + console.log(`ACTUAL - `, stakingWrapper.toFloatingPoint(ownerReward, 18)); //expect(ownerReward).to.be.bignumber.equal(expectedOwnerReward); }); @@ -240,12 +240,8 @@ describe('Staking Core', () => { const alphaNumerator = new BigNumber(1); const alphaDenominator = new BigNumber(3); - /*const expectedOwnerReward = totalRewards - .times( - (ownerFees.div(totalFees)).squareRoot() - ).times( - (ownerStake.div(totalStake)).squareRoot() - ).dividedToIntegerBy(1); // 25000000000000000000*/ + // https://www.wolframalpha.com/input/?i=57.154398+*+(5.64375%2F29.00679)+%5E+(1%2F3)+*+(56+%2F+10906)+%5E+(1+-+1%2F3) + console.log(`EXPECTED - 0.9857...`); const ownerReward = await stakingWrapper.cobbDouglas( totalRewards, @@ -256,8 +252,8 @@ describe('Staking Core', () => { alphaNumerator, alphaDenominator ); - console.log(ownerReward); - console.log(stakingWrapper.toFloatingPoint(ownerReward, 18)); + //console.log(ownerReward); + console.log(`ACTUAL - `, stakingWrapper.toFloatingPoint(ownerReward, 18)); //expect(ownerReward).to.be.bignumber.equal(expectedOwnerReward); }); });