Skip to content
This repository has been archived by the owner on Jan 18, 2023. It is now read-only.

Commit

Permalink
Add function for calling update allocation with TWAP. (#379)
Browse files Browse the repository at this point in the history
Add function for calling update allocation with TWAP.
  • Loading branch information
bweick committed May 29, 2020
1 parent 840c065 commit 82af579
Show file tree
Hide file tree
Showing 14 changed files with 768 additions and 11 deletions.
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "setprotocol.js",
"version": "1.2.8-rc9",
"version": "1.2.8-rc10",
"description": "A javascript library for interacting with the Set protocol",
"keywords": [
"setProtocol.js",
Expand Down Expand Up @@ -71,7 +71,7 @@
"set-protocol-oracles": "^1.0.16",
"set-protocol-strategies": "^1.1.39",
"set-protocol-viewers": "^1.0.13",
"set-protocol-utils": "^1.1.2",
"set-protocol-utils": "^1.1.3",
"timekeeper": "^2.1.2",
"tiny-promisify": "^1.0.0",
"truffle": "^5.1.12",
Expand Down
88 changes: 84 additions & 4 deletions src/api/SocialTradingAPI.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
Copyright 2018 Set Labs Inc.
Copyright 2019 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.
Expand All @@ -26,8 +26,10 @@ import {
ProtocolViewerWrapper,
RebalancingSetTokenV2Wrapper,
RebalancingSetTokenV3Wrapper,
SocialAllocatorWrapper,
SocialTradingManagerWrapper,
SocialTradingManagerV2Wrapper
SocialTradingManagerV2Wrapper,
TWAPLiquidatorWrapper,
} from '../wrappers';
import { Assertions } from '../assertions';
import { coreAPIErrors } from '../errors';
Expand All @@ -38,7 +40,8 @@ import {
SetProtocolConfig,
Tx,
EntryFeePaid,
RebalanceFeePaid
RebalanceFeePaid,
Bounds
} from '../types/common';

import {
Expand All @@ -61,12 +64,14 @@ const { SetProtocolUtils: SetUtils } = setProtocolUtils;
export class SocialTradingAPI {
private web3: Web3;
private assert: Assertions;
private performanceFeeCalculator: PerformanceFeeCalculatorWrapper;
private protocolViewer: ProtocolViewerWrapper;
private socialAllocator: SocialAllocatorWrapper;
private socialTradingManager: SocialTradingManagerWrapper;
private socialTradingManagerV2: SocialTradingManagerV2Wrapper;
private rebalancingSetV2: RebalancingSetTokenV2Wrapper;
private rebalancingSetV3: RebalancingSetTokenV3Wrapper;
private performanceFeeCalculator: PerformanceFeeCalculatorWrapper;
private twapLiquidator: TWAPLiquidatorWrapper;

/**
* Instantiates a new RebalancingManagerAPI instance that contains methods for issuing and redeeming Sets
Expand All @@ -79,11 +84,13 @@ export class SocialTradingAPI {
constructor(web3: Web3, assertions: Assertions, config: SetProtocolConfig) {
this.web3 = web3;
this.protocolViewer = new ProtocolViewerWrapper(web3, config.protocolViewerAddress);
this.socialAllocator = new SocialAllocatorWrapper(web3);
this.socialTradingManager = new SocialTradingManagerWrapper(web3);
this.socialTradingManagerV2 = new SocialTradingManagerV2Wrapper(web3);
this.rebalancingSetV2 = new RebalancingSetTokenV2Wrapper(web3);
this.rebalancingSetV3 = new RebalancingSetTokenV3Wrapper(web3);
this.performanceFeeCalculator = new PerformanceFeeCalculatorWrapper(web3);
this.twapLiquidator = new TWAPLiquidatorWrapper(web3);

this.assert = assertions;
}
Expand Down Expand Up @@ -291,6 +298,47 @@ export class SocialTradingAPI {
);
}

/**
* Calls SocialTradingManager's updateAllocation function. This function creates a new collateral Set and
* calls startRebalance on RebalancingSetTokenV2 using a TWAPLiquidator Updates allocation state on Manager
* contract.
*
* @param manager Address of the social trading manager contract
* @param tradingPool Address of tradingPool being updated
* @param newAllocation New allocation amount in base asset percentage
* @param chunkSize Value to be auctioned in each chunk
* @param chunkAuctionPeriod Time between chunk auctions
* @param txOpts Transaction options object conforming to `Tx` with signer, gas, and
* gasPrice data
* @return The hash of the resulting transaction.
*/
public async updateAllocationWithTWAPAsync(
manager: Address,
tradingPool: Address,
newAllocation: BigNumber,
chunkSize: BigNumber,
chunkAuctionPeriod: BigNumber,
txOpts: Tx,
): Promise<string> {
await this.assertUpdateAllocationWithTWAP(
manager,
tradingPool,
newAllocation,
chunkSize,
chunkAuctionPeriod,
txOpts
);

const liquidatorData = SetUtils.generateTWAPLiquidatorCalldata(chunkSize, chunkAuctionPeriod);
return this.socialTradingManager.updateAllocation(
manager,
tradingPool,
newAllocation,
liquidatorData,
txOpts
);
}

/**
* Calls tradingPool to accrue fees to manager.
*
Expand Down Expand Up @@ -711,6 +759,15 @@ export class SocialTradingAPI {

/* ============ Private Functions ============ */

private async getTradingPoolAssetPair(
allocator: Address
): Promise<[Address, Address]> {
const baseAsset = await this.socialAllocator.baseAsset(allocator);
const quoteAsset = await this.socialAllocator.quoteAsset(allocator);

return [baseAsset, quoteAsset];
}

private createNewTradingPoolObject(
newPoolInfo: any,
): NewTradingPoolInfo {
Expand Down Expand Up @@ -935,6 +992,29 @@ export class SocialTradingAPI {
this.assertValidAllocation(newAllocation);
}

private async assertUpdateAllocationWithTWAP(
manager: Address,
tradingPool: Address,
newAllocation: BigNumber,
chunkSize: BigNumber,
chunkAuctionPeriod: BigNumber,
txOpts: Tx,
): Promise <void> {
const poolInfo = await this.fetchNewTradingPoolV2DetailsAsync(tradingPool);

const assetPair = await this.getTradingPoolAssetPair(poolInfo.allocator);
const chunkSizeBounds: Bounds = await this.twapLiquidator.chunkSizeWhiteList(
poolInfo.liquidator,
assetPair[0],
assetPair[1]
);
this.assert.socialTrading.chunkSizeIsBetweenBounds(chunkSizeBounds, chunkSize);

this.assert.socialTrading.chunkAuctionPeriodGreaterOrEqualToZero(chunkAuctionPeriod);

await this.assertUpdateAllocation(manager, tradingPool, newAllocation, txOpts);
}

private async assertInitiateEntryFeeChange(
manager: Address,
tradingPool: Address,
Expand Down
26 changes: 26 additions & 0 deletions src/assertions/SocialTradingAssertions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import {
import { CommonAssertions } from './CommonAssertions';
import { coreAPIErrors, socialTradingErrors } from '../errors';
import { BigNumber, ether } from '../util';
import { Bounds } from '../types/common';
import { ZERO } from '../constants';

const moment = require('moment');
Expand Down Expand Up @@ -128,6 +129,31 @@ export class SocialTradingAssertions {
);
}

/**
* Throws if chunkSize is not between bounds
*
* @param bounds Asset pair volume bounds
* @param chunkSize Value of each chunk
*/
public chunkSizeIsBetweenBounds(bounds: Bounds, chunkSize: BigNumber): void {
if (chunkSize > bounds.upper || chunkSize < bounds.lower) {
throw new Error(socialTradingErrors.INVALID_CHUNK_SIZE(bounds));
}
}

/**
* Throws if chunkAuctionPeriod less than 0.
*
* @param chunkAuctionPeriod Time between chunk auctions
*/
public chunkAuctionPeriodGreaterOrEqualToZero(chunkAuctionPeriod: BigNumber): void {
this.commonAssertions.isGreaterOrEqualThan(
chunkAuctionPeriod,
ZERO,
coreAPIErrors.QUANTITY_NEEDS_TO_BE_POSITIVE(chunkAuctionPeriod)
);
}

/**
* Throws if caller is not the trader of tradingPool
*
Expand Down
3 changes: 3 additions & 0 deletions src/errors/socialTradingErrors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
'use strict';
import { Address } from 'set-protocol-utils';
import { BigNumber } from '../util';
import { Bounds } from '../types/common';

export const socialTradingErrors = {
ALLOCATION_EXCEEDS_ONE_HUNDERED_PERCENT: (allocation: BigNumber) => `Provided allocation ` +
Expand All @@ -31,4 +32,6 @@ export const socialTradingErrors = {
FEE_UPDATE_NOT_INITIATED: () => `Must call initiateEntryFeeChange first to start fee update process.`,
INSUFFICIENT_TIME_PASSED: (validUpdateTimestamp: string) => `Attempting to finalize fee update too soon. ` +
`Update available at ${validUpdateTimestamp}`,
INVALID_CHUNK_SIZE: (bounds: Bounds) => `Passed chunk size must be between ${bounds.lower} and` +
` ${bounds.upper}.`,
};
5 changes: 5 additions & 0 deletions src/types/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,11 @@ export const BidderHelperType = {
CTOKEN: new BigNumber(1),
};

export interface Bounds {
lower: BigNumber;
upper: BigNumber;
}

export interface EntryFeePaid {
transactionHash: string;
feeRecipient: Address;
Expand Down
1 change: 1 addition & 0 deletions src/wrappers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ export { MovingAverageOracleWrapper } from './strategies/MovingAverageOracleWrap
export { MACOStrategyManagerWrapper } from './strategies/MACOStrategyManagerWrapper';
export { MACOStrategyManagerV2Wrapper } from './strategies/MACOStrategyManagerV2Wrapper';
export { OracleProxyWrapper } from './strategies/OracleProxyWrapper';
export { SocialAllocatorWrapper } from './strategies/SocialAllocatorWrapper';
export { SocialTradingManagerWrapper } from './strategies/SocialTradingManagerWrapper';
export { SocialTradingManagerV2Wrapper } from './strategies/SocialTradingManagerV2Wrapper';
export { StrategyContractWrapper } from './strategies/StrategyContractWrapper';
Expand Down
22 changes: 22 additions & 0 deletions src/wrappers/set_protocol/TWAPLiquidatorWrapper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,4 +58,26 @@ export class TWAPLiquidatorWrapper {
txOpts
);
}

/**
* Returns chunk size asset bounds for a pair of assets
*
* @param liquidatorAddress Address of TWAPLiquidator contract
* @param assetOne Address of Asset one in pair
* @param assetTwo Address of Asset two in pair
*/
public async chunkSizeWhiteList(
liquidatorAddress: Address,
assetOne: Address,
assetTwo: Address,
): Promise<any> {
const liquidatorInstance = await this.contracts.loadTWAPLiquidatorContract(
liquidatorAddress
);

return await liquidatorInstance.chunkSizeWhiteList.callAsync(
assetOne,
assetTwo
);
}
}
71 changes: 71 additions & 0 deletions src/wrappers/strategies/SocialAllocatorWrapper.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/*
Copyright 2020 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.
*/

'use strict';

import Web3 from 'web3';

import { StrategyContractWrapper } from './StrategyContractWrapper';
import { Address } from '../../types/common';

/**
* @title SocialAllocatorWrapper
* @author Set Protocol
*
* The SocialAllocatorWrapper handles all functions on the SocialAllocator contract
*
*/
export class SocialAllocatorWrapper {
public web3: Web3;
public contracts: StrategyContractWrapper;

public constructor(web3: Web3) {
this.web3 = web3;
this.contracts = new StrategyContractWrapper(this.web3);
}

/**
* Get base asset of a social allocator
*
* @param socialAllocator Address of the SocialAllocator contract
* @return Base asset addresss
*/
public async baseAsset(
allocatorAddress: Address,
): Promise<Address> {
const allocatorInstance = await this.contracts.loadSocialAllocatorContractAsync(
allocatorAddress
);

return allocatorInstance.baseAsset.callAsync();
}

/**
* Get quote asset of a social allocator
*
* @param socialAllocator Address of the SocialAllocator contract
* @return Quote asset addresss
*/
public async quoteAsset(
allocatorAddress: Address,
): Promise<Address> {
const allocatorInstance = await this.contracts.loadSocialAllocatorContractAsync(
allocatorAddress
);

return allocatorInstance.quoteAsset.callAsync();
}
}
27 changes: 27 additions & 0 deletions src/wrappers/strategies/StrategyContractWrapper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import {
ETHDaiRebalancingManagerContract,
MACOStrategyManagerContract,
MACOStrategyManagerV2Contract,
SocialAllocatorContract,
SocialTradingManagerContract,
SocialTradingManagerV2Contract
} from 'set-protocol-strategies';
Expand Down Expand Up @@ -343,6 +344,32 @@ export class StrategyContractWrapper {
}
}

/**
* Load a SocialAllocator contract
*
* @param socialAllocator Address of the SocialAllocator contract
* @param transactionOptions Options sent into the contract deployed method
* @return The SocialAllocator Contract
*/
public async loadSocialAllocatorContractAsync(
socialAllocator: Address,
transactionOptions: object = {},
): Promise<SocialAllocatorContract> {
const cacheKey = `socialAllocator_${socialAllocator}`;

if (cacheKey in this.cache) {
return this.cache[cacheKey] as SocialAllocatorContract;
} else {
const socialAllocatorContract = await SocialAllocatorContract.at(
socialAllocator,
this.web3,
transactionOptions,
);
this.cache[cacheKey] = socialAllocatorContract;
return socialAllocatorContract;
}
}

/**
* Load a SocialTradingManager contract
*
Expand Down

0 comments on commit 82af579

Please sign in to comment.