Skip to content
This repository was archived by the owner on Jan 18, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
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
1 change: 1 addition & 0 deletions contracts/core/interfaces/IRebalancingSetFactory.sol
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
pragma solidity 0.4.25;

import { ISetFactory } from "./ISetFactory.sol";
import { IWhiteList } from "./IWhiteList.sol";


/**
Expand Down
54 changes: 54 additions & 0 deletions contracts/core/interfaces/IWhiteList.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*
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;

/**
* @title IWhiteList
* @author Set Protocol
*
* The IWhiteList interface exposes the whitelist mapping to check components
*/
interface IWhiteList {

/* ============ External Functions ============ */

/**
* Validates address against white list
*
* @param _address Address to check
Copy link
Contributor

Choose a reason for hiding this comment

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

return javadoc

Copy link
Contributor Author

Choose a reason for hiding this comment

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

+1

* @return bool Whether passed in address is whitelisted
*/
function whiteList(
address _address
)
external
view
returns(bool);

/**
* Verifies an array of addresses against the whitelist
*
* @param _addresses Array of addresses to verify
* @return bool Whether all addresses in the list are whitelsited
*/
function areValidAddresses(
address[] _addresses
)
external
view
returns(bool);
}
7 changes: 6 additions & 1 deletion contracts/core/tokens/RebalancingSetToken.sol
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import { ICore } from "../interfaces/ICore.sol";
import { IRebalancingSetFactory } from "../interfaces/IRebalancingSetFactory.sol";
import { ISetToken } from "../interfaces/ISetToken.sol";
import { IVault } from "../interfaces/IVault.sol";
import { IWhiteList } from "../interfaces/IWhiteList.sol";
import { RebalancingHelperLibrary } from "../lib/RebalancingHelperLibrary.sol";
import { StandardFailAuctionLibrary } from "./rebalancing-libraries/StandardFailAuctionLibrary.sol";
import { StandardPlaceBidLibrary } from "./rebalancing-libraries/StandardPlaceBidLibrary.sol";
Expand Down Expand Up @@ -58,7 +59,6 @@ contract RebalancingSetToken is
uint256 constant MIN_AUCTION_TIME_TO_PIVOT = 21600;
uint256 constant MAX_AUCTION_TIME_TO_PIVOT = 259200;


/* ============ Enums ============ */

enum State { Default, Proposal, Rebalance }
Expand All @@ -73,6 +73,7 @@ contract RebalancingSetToken is
// Core and Vault instances
ICore private coreInstance;
IVault private vaultInstance;
IWhiteList private componentWhiteListInstance;

// All rebalancingSetTokens have same natural unit, still allows for
// small amounts to be issued and attempts to reduce slippage as much
Expand Down Expand Up @@ -129,6 +130,7 @@ contract RebalancingSetToken is
* @param _initialUnitShares Units of currentSet that equals one share
* @param _proposalPeriod Amount of time for users to inspect a rebalance proposal
* @param _rebalanceInterval Minimum amount of time between rebalances
* @param _componentWhiteList Address of component WhiteList contract
* @param _name The name of the new RebalancingSetToken
* @param _symbol The symbol of the new RebalancingSetToken
*/
Expand All @@ -140,6 +142,7 @@ contract RebalancingSetToken is
uint256 _initialUnitShares,
uint256 _proposalPeriod,
uint256 _rebalanceInterval,
address _componentWhiteList,
string _name,
string _symbol
)
Expand Down Expand Up @@ -177,6 +180,7 @@ contract RebalancingSetToken is
coreInstance = ICore(core);
vault = coreInstance.vault();
vaultInstance = IVault(vault);
componentWhiteListInstance = IWhiteList(_componentWhiteList);
factory = _factory;
manager = _manager;
currentSet = _initialSet;
Expand Down Expand Up @@ -226,6 +230,7 @@ contract RebalancingSetToken is
_auctionTimeToPivot,
_auctionStartPrice,
_auctionPivotPrice,
componentWhiteListInstance,
proposeParameters
);

Expand Down
8 changes: 8 additions & 0 deletions contracts/core/tokens/RebalancingSetTokenFactory.sol
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import { Bytes32 } from "../../lib/Bytes32.sol";
import { ICore } from "../interfaces/ICore.sol";
import { LibBytes } from "../../external/0x/LibBytes.sol";
import { RebalancingSetToken } from "./RebalancingSetToken.sol";
import { IWhiteList } from "../interfaces/IWhiteList.sol";


/**
Expand All @@ -41,6 +42,9 @@ contract RebalancingSetTokenFactory {
// Address of the Core contract used to verify factory when creating a Set
address public core;

// Address of the WhiteList contract used to verify the tokens in a rebalance proposal
address public rebalanceComponentWhitelist;

// Minimum amount of time between rebalances in seconds
uint256 public minimumRebalanceInterval;

Expand All @@ -62,17 +66,20 @@ contract RebalancingSetTokenFactory {
* on RebalancingSetToken
*
* @param _core Address of deployed core contract
* @param _componentWhitelist Address of deployed whitelist contract
* @param _minimumRebalanceInterval Minimum amount of time between rebalances in seconds
* @param _minimumProposalPeriod Minimum amount of time users can review proposals in seconds
*/
constructor(
address _core,
address _componentWhitelist,
uint256 _minimumRebalanceInterval,
uint256 _minimumProposalPeriod
)
public
{
core = _core;
rebalanceComponentWhitelist = IWhiteList(_componentWhitelist);
minimumRebalanceInterval = _minimumRebalanceInterval;
minimumProposalPeriod = _minimumProposalPeriod;
}
Expand Down Expand Up @@ -151,6 +158,7 @@ contract RebalancingSetTokenFactory {
_units[0],
parameters.proposalPeriod,
parameters.rebalanceInterval,
rebalanceComponentWhitelist,
_name.bytes32ToString(),
_symbol.bytes32ToString()
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import { SafeMath } from "openzeppelin-solidity/contracts/math/SafeMath.sol";
import { IAuctionPriceCurve } from "../../lib/auction-price-libraries/IAuctionPriceCurve.sol";
import { ICore } from "../../interfaces/ICore.sol";
import { ISetToken } from "../../interfaces/ISetToken.sol";
import { IWhiteList } from "../../interfaces/IWhiteList.sol";
import { RebalancingHelperLibrary } from "../../lib/RebalancingHelperLibrary.sol";


Expand All @@ -35,10 +36,12 @@ library StandardProposeLibrary {
using SafeMath for uint256;

/* ============ Constants ============ */

uint256 constant MIN_AUCTION_TIME_TO_PIVOT = 21600;
uint256 constant MAX_AUCTION_TIME_TO_PIVOT = 259200;

/* ============ Structs ============ */

struct ProposeAuctionParameters {
address manager;
address currentSet;
Expand All @@ -58,6 +61,7 @@ library StandardProposeLibrary {
* @param _auctionTimeToPivot The amount of time for the auction to go ffrom start to pivot price
* @param _auctionStartPrice The price to start the auction at
* @param _auctionPivotPrice The price at which the price curve switches from linear to exponential
* @param _componentWhiteList Instance of component WhiteList to verify
* @param _proposeParameters Rebalancing Set Token state parameters needed to execute logic
* @return Struct containing auction price curve parameters
*/
Expand All @@ -67,6 +71,7 @@ library StandardProposeLibrary {
uint256 _auctionTimeToPivot,
uint256 _auctionStartPrice,
uint256 _auctionPivotPrice,
IWhiteList _componentWhiteList,
ProposeAuctionParameters memory _proposeParameters
)
internal
Expand Down Expand Up @@ -99,6 +104,13 @@ library StandardProposeLibrary {
"RebalancingSetToken.propose: Invalid or disabled proposed SetToken address"
);

// Check proposed components on whitelist. This is to ensure managers are unable to add contract addresses
// to a propose that prohibit the set from carrying out an auction i.e. a token that only the manager possesses
require(
_componentWhiteList.areValidAddresses(ISetToken(_nextSet).getComponents()),
"RebalancingSetToken.propose: Proposed set contains invalid component token"
);

// Check that the auction library is a valid priceLibrary tracked by Core
require(
_proposeParameters.coreInstance.validPriceLibraries(_auctionLibrary),
Expand Down
24 changes: 23 additions & 1 deletion contracts/lib/WhiteList.sol
Original file line number Diff line number Diff line change
Expand Up @@ -139,4 +139,26 @@ contract WhiteList is
{
return addresses;
}
}

/**
* Verifies an array of addresses against the whitelist
*
* @param _addresses Array of addresses to verify
* @return bool Whether all addresses in the list are whitelsited
*/
function areValidAddresses(
address[] _addresses
)
external
view
returns(bool)
{
for (uint256 i = 0; i < _addresses.length; i++) {
if (!whiteList[_addresses[i]]) {
return false;
}
}

return true;
}
}
25 changes: 19 additions & 6 deletions test/contracts/core/extensions/coreIssuance.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import {
SignatureValidatorContract,
StandardTokenMockContract,
TransferProxyContract,
VaultContract
VaultContract,
} from '@utils/contracts';
import { ether } from '@utils/units';
import { assertTokenBalanceAsync, expectRevertError } from '@utils/tokenAssertions';
Expand Down Expand Up @@ -59,7 +59,6 @@ contract('CoreIssuance', accounts => {
let transferProxy: TransferProxyContract;
let vault: VaultContract;
let setTokenFactory: SetTokenFactoryContract;
let rebalancingTokenFactory: RebalancingSetTokenFactoryContract;
let signatureValidator: SignatureValidatorContract;

const coreWrapper = new CoreWrapper(ownerAccount, ownerAccount);
Expand Down Expand Up @@ -87,11 +86,7 @@ contract('CoreIssuance', accounts => {
signatureValidator = await coreWrapper.deploySignatureValidatorAsync();
core = await coreWrapper.deployCoreAsync(transferProxy, vault, signatureValidator);
setTokenFactory = await coreWrapper.deploySetTokenFactoryAsync(core.address);
rebalancingTokenFactory = await coreWrapper.deployRebalancingSetTokenFactoryAsync(
core.address,
);
await coreWrapper.setDefaultStateAndAuthorizationsAsync(core, vault, transferProxy, setTokenFactory);
await coreWrapper.addFactoryAsync(core, rebalancingTokenFactory);
});

afterEach(async () => {
Expand Down Expand Up @@ -363,6 +358,8 @@ contract('CoreIssuance', accounts => {
let subjectQuantityToIssue: BigNumber;
let subjectSetToIssue: Address;

let rebalancingTokenFactory: RebalancingSetTokenFactoryContract;

let vanillaQuantityToIssue: BigNumber;
let vanillaSetToIssue: Address;

Expand All @@ -373,6 +370,13 @@ contract('CoreIssuance', accounts => {
let rebalancingSetToken: RebalancingSetTokenContract;

beforeEach(async () => {
const rebalancingComponentWhiteList = await coreWrapper.deployWhiteListAsync();
rebalancingTokenFactory = await coreWrapper.deployRebalancingSetTokenFactoryAsync(
core.address,
rebalancingComponentWhiteList.address
);
await coreWrapper.addFactoryAsync(core, rebalancingTokenFactory);

const setTokens = await rebalancingTokenWrapper.createSetTokensAsync(
core,
setTokenFactory.address,
Expand Down Expand Up @@ -865,6 +869,8 @@ contract('CoreIssuance', accounts => {
let subjectQuantityToRedeem: BigNumber;
let subjectSetToRedeem: Address;

let rebalancingTokenFactory: RebalancingSetTokenFactoryContract;

let vanillaQuantityToIssue: BigNumber;
let vanillaSetToIssue: Address;

Expand All @@ -879,6 +885,13 @@ contract('CoreIssuance', accounts => {
let rebalancingToken: RebalancingSetTokenContract;

beforeEach(async () => {
const rebalancingComponentWhiteList = await coreWrapper.deployWhiteListAsync();
rebalancingTokenFactory = await coreWrapper.deployRebalancingSetTokenFactoryAsync(
core.address,
rebalancingComponentWhiteList.address
);
await coreWrapper.addFactoryAsync(core, rebalancingTokenFactory);

const setTokens = await rebalancingTokenWrapper.createSetTokensAsync(
core,
setTokenFactory.address,
Expand Down
Loading