Skip to content
This repository was archived by the owner on Jan 18, 2023. It is now read-only.
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
163 changes: 95 additions & 68 deletions contracts/core/RebalancingSetToken.sol
Original file line number Diff line number Diff line change
Expand Up @@ -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
setUpAuctionParameters();

// Redeem rounded quantity of current Sets and update
redeemCurrentSet();

// Update state parameters
auctionStartTime = block.timestamp;
Expand Down Expand Up @@ -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(
Expand All @@ -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;
}
Expand Down Expand Up @@ -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);
}

Expand Down Expand Up @@ -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 setUpAuctionParameters()
private
{
// Create interfaces for interacting with sets
Expand All @@ -753,6 +719,11 @@ contract RebalancingSetToken is
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();
Expand All @@ -762,36 +733,92 @@ 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 {
memoryCombinedNextSetUnits[i] = uint256(0);
}
}

// 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.
Expand Down