Skip to content
This repository was archived by the owner on Jan 18, 2023. It is now read-only.
11 changes: 11 additions & 0 deletions contracts/core/tokens/RebalancingSetToken.sol
Original file line number Diff line number Diff line change
Expand Up @@ -341,10 +341,21 @@ contract RebalancingSetToken is
function endFailedAuction()
external
{
(
,
uint256 calculatedUnitShares
) = StandardSettleRebalanceLibrary.calculateNextSetIssueQuantity(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we write another function in StandardSettleRebalanceLibrary called something like canPeformSuccessfulSettlement or so instead of passing through calculatedUnitShares?

totalSupply(),
naturalUnit,
nextSet,
vault
);

// Fail auction and either reset to Default state or kill Rebalancing Set Token and enter Drawdown
// state
uint8 integerRebalanceState = StandardFailAuctionLibrary.endFailedAuction(
startingCurrentSetAmount,
calculatedUnitShares,
currentSet,
core,
auctionParameters,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ library StandardFailAuctionLibrary {
* if bids have been placed. Reset to Default state if no bids placed.
*
* @param _startingCurrentSetAmount Amount of current set at beginning or rebalance
* @param _calculatedUnitShares Calculated unitShares amount if rebalance were to be settled
* @param _currentSet The Set that failed to rebalance
* @param _coreAddress Core address
* @param _auctionParameters Struct containing auction price curve parameters
Expand All @@ -51,6 +52,7 @@ library StandardFailAuctionLibrary {
*/
function endFailedAuction(
uint256 _startingCurrentSetAmount,
uint256 _calculatedUnitShares,
address _currentSet,
address _coreAddress,
RebalancingHelperLibrary.AuctionPriceParameters _auctionParameters,
Expand All @@ -77,30 +79,41 @@ library StandardFailAuctionLibrary {
"RebalanceAuctionModule.endFailedAuction: Can only be called after auction reaches pivot"
);

// If settleRebalance can be called than endFailedAuction can't be
require(
_biddingParameters.remainingCurrentSets >= _biddingParameters.minimumBid,
"RebalancingSetToken.endFailedAuction: Cannot be called if rebalance is completed"
);

// Declare rebalance state variable
RebalancingHelperLibrary.State _newRebalanceState;

// Check if any bids have been placed
if (_startingCurrentSetAmount == _biddingParameters.remainingCurrentSets) {
// If bid not placed, reissue current Set
ICore(_coreAddress).issueInVault(
_currentSet,
_startingCurrentSetAmount
);

// Set Rebalance Set Token state to Default
_newRebalanceState = RebalancingHelperLibrary.State.Default;
uint8 newRebalanceState;
/**
* If not enough sets have been bid on then allow auction to fail where no bids being registered
* returns the rebalancing set token to pre-auction state and some bids being registered puts the
* rebalancing set token in Drawdown mode.
*
* However, if enough sets have been bid on. Then allow auction to fail and enter Drawdown state if
* and only if the calculated post-auction unitShares is equal to 0.
*/
if (_biddingParameters.remainingCurrentSets >= _biddingParameters.minimumBid) {
// Check if any bids have been placed
if (_startingCurrentSetAmount == _biddingParameters.remainingCurrentSets) {
// If bid not placed, reissue current Set
ICore(_coreAddress).issueInVault(
_currentSet,
_startingCurrentSetAmount
);

// Set Rebalance Set Token state to Default
newRebalanceState = uint8(RebalancingHelperLibrary.State.Default);
} else {
// Set Rebalancing Set Token to Drawdown state
newRebalanceState = uint8(RebalancingHelperLibrary.State.Drawdown);
}
} else {
// Set Rebalancing Set Token to Drawdown state
_newRebalanceState = RebalancingHelperLibrary.State.Drawdown;
// If settleRebalance can be called then endFailedAuction can't be
require(
_calculatedUnitShares == 0,
"RebalancingSetToken.endFailedAuction: Cannot be called if rebalance is viably completed"
);

// If calculated unitShares equals 0 set to Drawdown state
newRebalanceState = uint8(RebalancingHelperLibrary.State.Drawdown);
}

return uint8(_newRebalanceState);
return newRebalanceState;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,11 @@ library StandardSettleRebalanceLibrary {
_vaultAddress
);

require(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

canPeformSuccessfulSettlement function result would be more clear

nextUnitShares > 0,
"RebalancingSetToken.settleRebalance: Failed rebalance, unitshares equals 0. Call endFailedAuction."
);

// Issue nextSet to RebalancingSetToken
ICore(_coreAddress).issueInVault(
_nextSet,
Expand Down Expand Up @@ -132,7 +137,7 @@ library StandardSettleRebalanceLibrary {
_vaultAddress,
setDetails
);

// Calculate the amount of naturalUnits worth of rebalancingSetToken outstanding
uint256 naturalUnitsOutstanding = _totalSupply.div(_naturalUnit);

Expand Down Expand Up @@ -201,6 +206,6 @@ library StandardSettleRebalanceLibrary {
}
}

return maxIssueAmount;
return maxIssueAmount;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -88,13 +88,13 @@ library StandardStartRebalanceLibrary {
// Must be in "Proposal" state before going into "Rebalance" state
require(
_rebalanceState == uint8(RebalancingHelperLibrary.State.Proposal),
"RebalancingSetToken.rebalance: State must be Proposal"
"RebalancingSetToken.startRebalance: State must be Proposal"
);

// Be sure the full proposal period has elapsed
require(
block.timestamp >= _proposalStartTime.add(_proposalPeriod),
"RebalancingSetToken.rebalance: Proposal period not elapsed"
"RebalancingSetToken.startRebalance: Proposal period not elapsed"
);

// Create combined array data structures and calculate minimum bid needed for auction
Expand All @@ -111,6 +111,13 @@ library StandardStartRebalanceLibrary {
_vaultAddress
);

// Require remainingCurrentSets to be greater than minimumBid otherwise no bidding would
// be allowed
require(
biddingParameters.remainingCurrentSets >= biddingParameters.minimumBid,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we also have a function in settleLibrary to reflect this equality? It's also in endFailedAuction

"RebalancingSetToken.startRebalance: Not enough collateral to rebalance"
);

return biddingParameters;
}

Expand Down
58 changes: 58 additions & 0 deletions contracts/mocks/core/lib/UpdatableConstantAuctionPriceCurve.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/*
Copyright 2018 Set Labs Inc.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

pragma solidity 0.4.25;
pragma experimental "ABIEncoderV2";

import { SafeMath } from "openzeppelin-solidity/contracts/math/SafeMath.sol";
import { ConstantAuctionPriceCurve } from "./ConstantAuctionPriceCurve.sol";
import { RebalancingHelperLibrary } from "../../../core/lib/RebalancingHelperLibrary.sol";

/**
* @title UpdatableConstantAuctionPriceCurve
* @author Set Protocol
*
* Contract used in rebalancing auction testing to return consistent price.
* !!!!!!!!!!!!! DO NOT DEPLOY !!!!!!!!!!!!!
*
*/

contract UpdatableConstantAuctionPriceCurve is ConstantAuctionPriceCurve {

constructor(
uint256 _priceNumerator,
uint256 _priceDenominator
)
public
ConstantAuctionPriceCurve(
_priceNumerator,
_priceDenominator
)
{}

/*
* Update constant auction price
*
* @param _newPrice Price to update to
*/
function updatePrice(
uint256 _newPrice
)
public
{
priceNumerator = _newPrice;
}
}
14 changes: 14 additions & 0 deletions test/contracts/core/modules/rebalanceAuctionModule.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -551,6 +551,13 @@ contract('RebalanceAuctionModule', accounts => {

describe('when getBidPrice is called from Rebalance State', async () => {
beforeEach(async () => {
// Issue currentSetToken
await coreMock.issue.sendTransactionAsync(currentSetToken.address, ether(9), {from: deployerAccount});
await erc20Wrapper.approveTransfersAsync([currentSetToken], transferProxy.address);

// Use issued currentSetToken to issue rebalancingSetToken
await coreMock.issue.sendTransactionAsync(rebalancingSetToken.address, ether(7));

await rebalancingWrapper.defaultTransitionToRebalanceAsync(
coreMock,
rebalancingComponentWhiteList,
Expand Down Expand Up @@ -762,6 +769,13 @@ contract('RebalanceAuctionModule', accounts => {

describe('when placeBid is called from Rebalance State', async () => {
beforeEach(async () => {
// Issue currentSetToken
await coreMock.issue.sendTransactionAsync(currentSetToken.address, ether(9), {from: deployerAccount});
await erc20Wrapper.approveTransfersAsync([currentSetToken], transferProxy.address);

// Use issued currentSetToken to issue rebalancingSetToken
await coreMock.issue.sendTransactionAsync(rebalancingSetToken.address, ether(7));

await rebalancingWrapper.defaultTransitionToRebalanceAsync(
coreMock,
rebalancingComponentWhiteList,
Expand Down
Loading