From 0ec82c9582a9e488edfedab366a5556e79757343 Mon Sep 17 00:00:00 2001 From: felix2feng Date: Wed, 21 Nov 2018 18:04:00 -0800 Subject: [PATCH 1/3] First stab --- contracts/core/RebalancingSetToken.sol | 160 +++++++++++++++---------- 1 file changed, 96 insertions(+), 64 deletions(-) diff --git a/contracts/core/RebalancingSetToken.sol b/contracts/core/RebalancingSetToken.sol index bf92c17e2..8483af4c4 100644 --- a/contracts/core/RebalancingSetToken.sol +++ b/contracts/core/RebalancingSetToken.sol @@ -290,24 +290,11 @@ contract RebalancingSetToken is "RebalancingSetToken.rebalance: Proposal period not elapsed" ); - // Create token arrays needed for auction - auctionSetUp(); - - // Get currentSet natural unit - uint256 currentSetNaturalUnit = ISetToken(currentSet).naturalUnit(); - - // Get core address from factory and create core interface - ICore core = ICore(IRebalancingSetFactory(factory).core()); - - // Get remainingCurrentSets and make it divisible by currentSet natural unit - remainingCurrentSets = IVault(core.vault()).getOwnerBalance( - currentSet, - this - ); - remainingCurrentSets = remainingCurrentSets.div(currentSetNaturalUnit).mul(currentSetNaturalUnit); - - // Redeem current set held by rebalancing token in vault - core.redeemInVault(currentSet, remainingCurrentSets); + // Create combined array data structures and calculate minimum bid needed for auction + setUpAuctionDataStructures(); + + // Redeem rounded quantity of current Sets and update + redeemCurrentSet(); // Update state parameters auctionStartTime = block.timestamp; @@ -336,18 +323,14 @@ contract RebalancingSetToken is "RebalancingSetToken.settleRebalance: Rebalance not completed" ); - // Creating pointer to Core to Issue next set and Deposit into vault and to nextSet token - // to transfer fees ICore core = ICore(IRebalancingSetFactory(factory).core()); - ISetToken nextSetInstance = ISetToken(nextSet); - address protocolAddress = core.protocolAddress(); - // Issue nextSet to RebalancingSetToken - uint256 issueAmount; - uint256 totalFees; - uint256 managerFee; - uint256 protocolFee; - (issueAmount, unitShares, totalFees) = calculateNextSetIssueQuantity(); + // Calculate next Set quantities + ( + uint256 issueAmount, + uint256 nextUnitShares, + uint256 totalFees + ) = calculateNextSetIssueQuantity(); // Issue nextSet to RebalancingSetToken core.issue( @@ -369,30 +352,12 @@ contract RebalancingSetToken is issueAmount.sub(totalFees) ); - // If fees greater than 0, distribute - if (totalFees > 0) { - // Calculate fee split between protocol and manager - (managerFee, protocolFee) = calculateFeeSplit(totalFees); - - // Transfer fees to manager - nextSetInstance.transfer( - manager, - managerFee - ); - - // If necessary, transfer fees to protocolAddress - if (protocolFee > 0) { - nextSetInstance.transfer( - protocolAddress, - protocolFee - ); - } - } - - // Set current set to be rebalancing set - currentSet = nextSet; + // Resolve Fees to protocol and manager + resolveRebalanceFees(totalFees); // Update state parameters + unitShares = nextUnitShares; + currentSet = nextSet; lastRebalanceTimestamp = block.timestamp; rebalanceState = State.Default; } @@ -435,13 +400,14 @@ contract RebalancingSetToken is "RebalancingSetToken.placeBid: Bid exceeds remaining current sets" ); - // Calculate token inflow and outflow arrays - uint256[] memory inflowUnitArray = new uint256[](combinedTokenArray.length); - uint256[] memory outflowUnitArray = new uint256[](combinedTokenArray.length); - - (inflowUnitArray, outflowUnitArray) = getBidPrice(_quantity); + ( + uint256[] memory inflowUnitArray, + uint256[] memory outflowUnitArray + ) = getBidPrice(_quantity); + // Update remaining Set figure to transact remainingCurrentSets = remainingCurrentSets.sub(_quantity); + return (combinedTokenArray, inflowUnitArray, outflowUnitArray); } @@ -737,7 +703,7 @@ contract RebalancingSetToken is * Calcualate unit difference between both sets relative to the largest natural * unit of the two sets. */ - function auctionSetUp() + function setUpAuctionDataStructures() private { // Create interfaces for interacting with sets @@ -747,12 +713,18 @@ contract RebalancingSetToken is // Create combined token Array address[] memory oldComponents = currentSetInstance.getComponents(); address[] memory newComponents = nextSetInstance.getComponents(); + combinedTokenArray = oldComponents.union(newComponents); // Get naturalUnit of both sets uint256 currentSetNaturalUnit = currentSetInstance.naturalUnit(); uint256 nextSetNaturalUnit = nextSetInstance.naturalUnit(); + minimumBid = Math.max( + currentSetNaturalUnit.mul(auctionPriceDivisor), + nextSetNaturalUnit.mul(auctionPriceDivisor) + ); + // Get units arrays for both sets uint256[] memory currentSetUnits = currentSetInstance.getUnits(); uint256[] memory nextSetUnits = nextSetInstance.getUnits(); @@ -762,24 +734,19 @@ contract RebalancingSetToken is uint256[] memory memoryCombinedCurrentUnits = new uint256[](combinedTokenArray.length); uint256[] memory memoryCombinedNextSetUnits = new uint256[](combinedTokenArray.length); - minimumBid = Math.max( - currentSetNaturalUnit.mul(auctionPriceDivisor), - nextSetNaturalUnit.mul(auctionPriceDivisor) - ); - for (uint256 i = 0; i < combinedTokenArray.length; i++) { // Check if component in arrays and get index if it is (uint256 indexCurrent, bool isInCurrent) = oldComponents.indexOf(combinedTokenArray[i]); (uint256 indexRebalance, bool isInNext) = newComponents.indexOf(combinedTokenArray[i]); - // Compute and push unit amounts of token in currentSet, push 0 if not in set + // Compute and push unit amounts of token in currentSet if (isInCurrent) { memoryCombinedCurrentUnits[i] = computeTransferValue(currentSetUnits[indexCurrent], currentSetNaturalUnit); } else { memoryCombinedCurrentUnits[i] = uint256(0); } - // Compute and push unit amounts of token in nextSet, push 0 if not in set + // Compute and push unit amounts of token in nextSet if (isInNext) { memoryCombinedNextSetUnits[i] = computeTransferValue(nextSetUnits[indexRebalance], nextSetNaturalUnit); } else { @@ -787,11 +754,76 @@ contract RebalancingSetToken is } } - // Set combinedCurrentUnits and combinedNextSetUnits to memory versions of arrays + // Update State combinedCurrentUnits = memoryCombinedCurrentUnits; combinedNextSetUnits = memoryCombinedNextSetUnits; } + /** + * Calculates the fee split between the manager and protocol. Then transfers fee + * to each party. + * + * @param _totalFees Total amount of fees + */ + function resolveRebalanceFees( + uint256 _totalFees + ) + private + { + ISetToken nextSetInstance = ISetToken(nextSet); + ICore core = ICore(IRebalancingSetFactory(factory).core()); + address protocolAddress = core.protocolAddress(); + + // If fees greater than 0, distribute + if (_totalFees > 0) { + // Calculate fee split between protocol and manager + ( + uint256 managerFee, + uint256 protocolFee + ) = calculateFeeSplit(_totalFees); + + // Transfer fees to manager + nextSetInstance.transfer( + manager, + managerFee + ); + + // If necessary, transfer fees to protocolAddress + if (protocolFee > 0) { + nextSetInstance.transfer( + protocolAddress, + protocolFee + ); + } + } + } + + /** + * Calculates the maximum redemption quantity and redeems the Set into the vault. + * Also updates remainingCurrentSets state variable + * + */ + function redeemCurrentSet() + private + { + // Get core address from factory and create core interface + ICore core = ICore(IRebalancingSetFactory(factory).core()); + + // Get remainingCurrentSets and make it divisible by currentSet natural unit + uint256 currentSetBalance = IVault(core.vault()).getOwnerBalance( + currentSet, + this + ); + + // Calculates the set's natural unit + uint256 currentSetNaturalUnit = ISetToken(currentSet).naturalUnit(); + + // Rounds the redemption quantity to a multiple of the current Set natural unit and sets variable + remainingCurrentSets = currentSetBalance.div(currentSetNaturalUnit).mul(currentSetNaturalUnit); + + core.redeemInVault(currentSet, remainingCurrentSets); + } + /** * Calculate the amount of nextSets to issue by using the component amounts in the * vault, unitShares following from this calculation. From a844dd767767f942dce0660e693d14382cff9ebd Mon Sep 17 00:00:00 2001 From: felix2feng Date: Wed, 21 Nov 2018 18:15:01 -0800 Subject: [PATCH 2/3] Remove unused else statements --- contracts/core/RebalancingSetToken.sol | 4 ---- 1 file changed, 4 deletions(-) diff --git a/contracts/core/RebalancingSetToken.sol b/contracts/core/RebalancingSetToken.sol index 8483af4c4..69be27576 100644 --- a/contracts/core/RebalancingSetToken.sol +++ b/contracts/core/RebalancingSetToken.sol @@ -742,15 +742,11 @@ contract RebalancingSetToken is // Compute and push unit amounts of token in currentSet if (isInCurrent) { memoryCombinedCurrentUnits[i] = computeTransferValue(currentSetUnits[indexCurrent], currentSetNaturalUnit); - } else { - memoryCombinedCurrentUnits[i] = uint256(0); } // Compute and push unit amounts of token in nextSet if (isInNext) { memoryCombinedNextSetUnits[i] = computeTransferValue(nextSetUnits[indexRebalance], nextSetNaturalUnit); - } else { - memoryCombinedNextSetUnits[i] = uint256(0); } } From d7279272aea85bdb6fd13de747f74a2eb30fd38f Mon Sep 17 00:00:00 2001 From: felix2feng Date: Sun, 25 Nov 2018 20:13:31 -0800 Subject: [PATCH 3/3] Knits --- contracts/core/RebalancingSetToken.sol | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/contracts/core/RebalancingSetToken.sol b/contracts/core/RebalancingSetToken.sol index 69be27576..58b96df79 100644 --- a/contracts/core/RebalancingSetToken.sol +++ b/contracts/core/RebalancingSetToken.sol @@ -291,7 +291,7 @@ contract RebalancingSetToken is ); // Create combined array data structures and calculate minimum bid needed for auction - setUpAuctionDataStructures(); + setUpAuctionParameters(); // Redeem rounded quantity of current Sets and update redeemCurrentSet(); @@ -703,7 +703,7 @@ contract RebalancingSetToken is * Calcualate unit difference between both sets relative to the largest natural * unit of the two sets. */ - function setUpAuctionDataStructures() + function setUpAuctionParameters() private { // Create interfaces for interacting with sets @@ -713,7 +713,6 @@ contract RebalancingSetToken is // Create combined token Array address[] memory oldComponents = currentSetInstance.getComponents(); address[] memory newComponents = nextSetInstance.getComponents(); - combinedTokenArray = oldComponents.union(newComponents); // Get naturalUnit of both sets