From 61dd74020d5d23ba20399e58fc3adb898e6384e7 Mon Sep 17 00:00:00 2001 From: bweick Date: Mon, 30 Dec 2019 20:16:40 -0800 Subject: [PATCH] Brian/update protocol viewer (#556) Added batch fetching of fee info from tradingPools. Update contracts to interact with newest version of strategies. --- .../SocialTradingManagerMock.sol | 10 + contracts/viewer/lib/TradingPoolViewer.sol | 40 ++ package.json | 4 +- .../viewer/lib/tradingPoolViewer.spec.ts | 139 +++++ test/contracts/viewer/protocolViewer.spec.ts | 552 +++++++++--------- yarn.lock | 53 ++ 6 files changed, 519 insertions(+), 279 deletions(-) diff --git a/contracts/mocks/supplementary/SocialTradingManagerMock.sol b/contracts/mocks/supplementary/SocialTradingManagerMock.sol index 908f7ead7..73872fe8b 100644 --- a/contracts/mocks/supplementary/SocialTradingManagerMock.sol +++ b/contracts/mocks/supplementary/SocialTradingManagerMock.sol @@ -57,4 +57,14 @@ contract SocialTradingManagerMock { pools[address(_tradingPool)].currentAllocation = _newAllocation; } + + function updateFee( + address _tradingPool, + uint256 _newFee + ) + external + { + pools[_tradingPool].newEntryFee = _newFee; + pools[_tradingPool].feeUpdateTimestamp = block.timestamp; + } } diff --git a/contracts/viewer/lib/TradingPoolViewer.sol b/contracts/viewer/lib/TradingPoolViewer.sol index 2481fdfd3..964573045 100644 --- a/contracts/viewer/lib/TradingPoolViewer.sol +++ b/contracts/viewer/lib/TradingPoolViewer.sol @@ -138,6 +138,46 @@ contract TradingPoolViewer { return (poolInfo, tradingPoolInfo, collateralSetInfo); } + function batchFetchTradingPoolEntryFees( + IRebalancingSetTokenV2[] calldata _tradingPools + ) + external + view + returns (uint256[] memory) + { + // Cache length of addresses to fetch entryFees for + uint256 _poolCount = _tradingPools.length; + + // Instantiate output array in memory + uint256[] memory entryFees = new uint256[](_poolCount); + + for (uint256 i = 0; i < _poolCount; i++) { + entryFees[i] = _tradingPools[i].entryFee(); + } + + return entryFees; + } + + function batchFetchTradingPoolRebalanceFees( + IRebalancingSetTokenV2[] calldata _tradingPools + ) + external + view + returns (uint256[] memory) + { + // Cache length of addresses to fetch rebalanceFees for + uint256 _poolCount = _tradingPools.length; + + // Instantiate output array in memory + uint256[] memory rebalanceFees = new uint256[](_poolCount); + + for (uint256 i = 0; i < _poolCount; i++) { + rebalanceFees[i] = _tradingPools[i].rebalanceFee(); + } + + return rebalanceFees; + } + /* ============ Internal Functions ============ */ function getCollateralSetInfo( diff --git a/package.json b/package.json index 568f96bee..723f45bf4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "set-protocol-contracts", - "version": "1.3.13-beta", + "version": "1.3.14-beta", "description": "Smart contracts for {Set} Protocol", "main": "dist/artifacts/index.js", "typings": "dist/typings/artifacts/index.d.ts", @@ -98,7 +98,7 @@ "lint-staged": "^7.2.0", "module-alias": "^2.1.0", "openzeppelin-solidity": "^2.2", - "set-protocol-strategies": "^1.1.22", + "set-protocol-strategies": "^1.1.24", "set-protocol-utils": "^1.0.0-beta.44", "tiny-promisify": "^1.0.0", "truffle-flattener": "^1.4.0", diff --git a/test/contracts/viewer/lib/tradingPoolViewer.spec.ts b/test/contracts/viewer/lib/tradingPoolViewer.spec.ts index 5ff97a657..65d4f0c6c 100644 --- a/test/contracts/viewer/lib/tradingPoolViewer.spec.ts +++ b/test/contracts/viewer/lib/tradingPoolViewer.spec.ts @@ -218,6 +218,9 @@ contract('TradingPoolViewer', accounts => { let lastRebalanceTimestamp: BigNumber; let setManager: SocialTradingManagerMockContract; + let newFee: BigNumber; + let feeUpdateTimestamp: BigNumber; + beforeEach(async () => { currentSetToken = set1; @@ -246,6 +249,15 @@ contract('TradingPoolViewer', accounts => { currentAllocation ); + newFee = ether(.02); + await setManager.updateFee.sendTransactionAsync( + rebalancingSetToken.address, + newFee + ); + + const block = await web3.eth.getBlock('latest'); + feeUpdateTimestamp = new BigNumber(block.timestamp); + subjectTradingPool = rebalancingSetToken.address; }); @@ -261,6 +273,8 @@ contract('TradingPoolViewer', accounts => { expect(poolInfo.trader).to.equal(trader); expect(poolInfo.allocator).to.equal(allocator); expect(poolInfo.currentAllocation).to.be.bignumber.equal(currentAllocation); + expect(poolInfo.newEntryFee).to.be.bignumber.equal(newFee); + expect(poolInfo.feeUpdateTimestamp).to.be.bignumber.equal(feeUpdateTimestamp); }); it('fetches the correct RebalancingSetTokenV2/TradingPool data', async () => { @@ -366,6 +380,8 @@ contract('TradingPoolViewer', accounts => { expect(poolInfo.trader).to.equal(trader); expect(poolInfo.allocator).to.equal(allocator); expect(poolInfo.currentAllocation).to.be.bignumber.equal(newAllocation); + expect(poolInfo.newEntryFee).to.be.bignumber.equal(ZERO); + expect(poolInfo.feeUpdateTimestamp).to.be.bignumber.equal(ZERO); }); it('fetches the correct RebalancingSetTokenV2/TradingPool data', async () => { @@ -397,4 +413,127 @@ contract('TradingPoolViewer', accounts => { expect(collateralSetData.symbol).to.equal('SET'); }); }); + + describe('#batchFetchTradingPoolEntryFees', async () => { + let subjectTradingPools: Address[]; + + let rebalancingSetToken2: RebalancingSetTokenV2Contract; + let entryFee1: BigNumber; + let entryFee2: BigNumber; + + beforeEach(async () => { + const setManager = await viewerHelper.deploySocialTradingManagerMockAsync(); + + const failPeriod = ONE_DAY_IN_SECONDS; + const { timestamp } = await web3.eth.getBlock('latest'); + const lastRebalanceTimestamp = timestamp; + + entryFee1 = ether(.02); + rebalancingSetToken = await rebalancingHelper.createDefaultRebalancingSetTokenV2Async( + coreMock, + rebalancingFactory.address, + setManager.address, + liquidator.address, + feeRecipient, + fixedFeeCalculator.address, + set1.address, + failPeriod, + lastRebalanceTimestamp, + entryFee1 + ); + + entryFee2 = ether(.03); + rebalancingSetToken2 = await rebalancingHelper.createDefaultRebalancingSetTokenV2Async( + coreMock, + rebalancingFactory.address, + setManager.address, + liquidator.address, + feeRecipient, + fixedFeeCalculator.address, + set1.address, + failPeriod, + lastRebalanceTimestamp, + entryFee2 + ); + + subjectTradingPools = [rebalancingSetToken.address, rebalancingSetToken2.address]; + }); + + async function subject(): Promise { + return poolViewer.batchFetchTradingPoolEntryFees.callAsync( + subjectTradingPools + ); + } + + it('fetches the correct entryFee array', async () => { + const actualEntryFeeArray = await subject(); + + const expectedEntryFeeArray = [entryFee1, entryFee2]; + + expect(JSON.stringify(actualEntryFeeArray)).to.equal(JSON.stringify(expectedEntryFeeArray)); + }); + }); + + describe('#batchFetchTradingPoolRebalanceFees', async () => { + let subjectTradingPools: Address[]; + + let rebalancingSetToken2: RebalancingSetTokenV2Contract; + let rebalanceFee1: BigNumber; + let rebalanceFee2: BigNumber; + + beforeEach(async () => { + const setManager = await viewerHelper.deploySocialTradingManagerMockAsync(); + + const failPeriod = ONE_DAY_IN_SECONDS; + const { timestamp } = await web3.eth.getBlock('latest'); + const lastRebalanceTimestamp = timestamp; + const entryFee = ether(.02); + + rebalanceFee1 = ether(.002); + rebalancingSetToken = await rebalancingHelper.createDefaultRebalancingSetTokenV2Async( + coreMock, + rebalancingFactory.address, + setManager.address, + liquidator.address, + feeRecipient, + fixedFeeCalculator.address, + set1.address, + failPeriod, + lastRebalanceTimestamp, + entryFee, + rebalanceFee1 + ); + + rebalanceFee2 = ether(.003); + rebalancingSetToken2 = await rebalancingHelper.createDefaultRebalancingSetTokenV2Async( + coreMock, + rebalancingFactory.address, + setManager.address, + liquidator.address, + feeRecipient, + fixedFeeCalculator.address, + set1.address, + failPeriod, + lastRebalanceTimestamp, + entryFee, + rebalanceFee2 + ); + + subjectTradingPools = [rebalancingSetToken.address, rebalancingSetToken2.address]; + }); + + async function subject(): Promise { + return poolViewer.batchFetchTradingPoolRebalanceFees.callAsync( + subjectTradingPools + ); + } + + it('fetches the correct rebalanceFee array', async () => { + const actualEntryRebalanceArray = await subject(); + + const expectedEntryRebalanceArray = [rebalanceFee1, rebalanceFee2]; + + expect(JSON.stringify(actualEntryRebalanceArray)).to.equal(JSON.stringify(expectedEntryRebalanceArray)); + }); + }); }); diff --git a/test/contracts/viewer/protocolViewer.spec.ts b/test/contracts/viewer/protocolViewer.spec.ts index 0387911c4..e2984a97e 100644 --- a/test/contracts/viewer/protocolViewer.spec.ts +++ b/test/contracts/viewer/protocolViewer.spec.ts @@ -341,7 +341,7 @@ contract('ProtocolViewer', accounts => { }); }); - describe('#fetchNewTradingPoolDetails', async () => { + describe('Trading Pool Tests', async () => { let rebalancingSetToken: RebalancingSetTokenV2Contract; let coreMock: CoreMockContract; @@ -389,8 +389,6 @@ contract('ProtocolViewer', accounts => { const feeCalculatorHelper = new FeeCalculatorHelper(deployerAccount); const viewerHelper = new ProtocolViewerHelper(deployerAccount); - let subjectTradingPool: Address; - let currentSetToken: SetTokenContract; let currentAllocation: BigNumber; let lastRebalanceTimestamp: BigNumber; @@ -492,288 +490,288 @@ contract('ProtocolViewer', accounts => { allocator, currentAllocation ); - - subjectTradingPool = rebalancingSetToken.address; - }); - - async function subject(): Promise { - return protocolViewer.fetchNewTradingPoolDetails.callAsync( - subjectTradingPool - ); - } - - it('fetches the correct poolInfo data', async () => { - const [ poolInfo, , ] = await subject(); - - expect(poolInfo.trader).to.equal(trader); - expect(poolInfo.allocator).to.equal(allocator); - expect(poolInfo.currentAllocation).to.be.bignumber.equal(currentAllocation); }); - it('fetches the correct RebalancingSetTokenV2/TradingPool data', async () => { - const [ , rbSetData, ] = await subject(); - - expect(rbSetData.manager).to.equal(setManager.address); - expect(rbSetData.feeRecipient).to.equal(feeRecipient); - expect(rbSetData.currentSet).to.equal(currentSetToken.address); - expect(rbSetData.name).to.equal('Rebalancing Set Token'); - expect(rbSetData.symbol).to.equal('RBSET'); - expect(rbSetData.unitShares).to.be.bignumber.equal(DEFAULT_UNIT_SHARES); - expect(rbSetData.naturalUnit).to.be.bignumber.equal(DEFAULT_REBALANCING_NATURAL_UNIT); - expect(rbSetData.rebalanceInterval).to.be.bignumber.equal(ONE_DAY_IN_SECONDS); - expect(rbSetData.entryFee).to.be.bignumber.equal(ZERO); - expect(rbSetData.rebalanceFee).to.be.bignumber.equal(ZERO); - expect(rbSetData.lastRebalanceTimestamp).to.be.bignumber.equal(lastRebalanceTimestamp); - expect(rbSetData.rebalanceState).to.be.bignumber.equal(ZERO); - }); - - it('fetches the correct CollateralSet data', async () => { - const [ , , collateralSetData ] = await subject(); - - expect(JSON.stringify(collateralSetData.components)).to.equal(JSON.stringify(set1Components)); - expect(JSON.stringify(collateralSetData.units)).to.equal(JSON.stringify(set1Units)); - expect(collateralSetData.naturalUnit).to.be.bignumber.equal(set1NaturalUnit); - expect(collateralSetData.name).to.equal('Set Token'); - expect(collateralSetData.symbol).to.equal('SET'); - }); - }); - - describe('#fetchTradingPoolRebalanceDetails', async () => { - let rebalancingSetToken: RebalancingSetTokenV2Contract; - - let coreMock: CoreMockContract; - let transferProxy: TransferProxyContract; - let vault: VaultContract; - let setTokenFactory: SetTokenFactoryContract; - let rebalancingFactory: RebalancingSetTokenV2FactoryContract; - let rebalancingComponentWhiteList: WhiteListContract; - let liquidatorWhitelist: WhiteListContract; - let liquidator: LinearAuctionLiquidatorContract; - let fixedFeeCalculator: FixedFeeCalculatorContract; - let feeCalculatorWhitelist: WhiteListContract; - - let name: string; - let auctionPeriod: BigNumber; - let rangeStart: BigNumber; - let rangeEnd: BigNumber; - let oracleWhiteList: OracleWhiteListContract; - - let component1: StandardTokenMockContract; - let component2: StandardTokenMockContract; - - let component1Price: BigNumber; - let component2Price: BigNumber; - - let set1: SetTokenContract; - let set2: SetTokenContract; - - let set1Components: Address[]; - let set1Units: BigNumber[]; - let set1NaturalUnit: BigNumber; - - let set2Components: Address[]; - let set2Units: BigNumber[]; - let set2NaturalUnit: BigNumber; - - let component1Oracle: UpdatableOracleMockContract; - let component2Oracle: UpdatableOracleMockContract; - - const coreHelper = new CoreHelper(deployerAccount, deployerAccount); - const erc20Helper = new ERC20Helper(deployerAccount); - const rebalancingHelper = new RebalancingSetV2Helper( - deployerAccount, - coreHelper, - erc20Helper, - blockchain - ); - const liquidatorHelper = new LiquidatorHelper(deployerAccount, erc20Helper); - const libraryMockHelper = new LibraryMockHelper(deployerAccount); - const feeCalculatorHelper = new FeeCalculatorHelper(deployerAccount); - const viewerHelper = new ProtocolViewerHelper(deployerAccount); - - let subjectTradingPool: Address; - - let setManager: SocialTradingManagerMockContract; - let newAllocation: BigNumber; - let nextSet: SetTokenContract; - - beforeEach(async () => { - transferProxy = await coreHelper.deployTransferProxyAsync(); - vault = await coreHelper.deployVaultAsync(); - coreMock = await coreHelper.deployCoreMockAsync(transferProxy, vault); - - setTokenFactory = await coreHelper.deploySetTokenFactoryAsync(coreMock.address); - rebalancingComponentWhiteList = await coreHelper.deployWhiteListAsync(); - liquidatorWhitelist = await coreHelper.deployWhiteListAsync(); - feeCalculatorWhitelist = await coreHelper.deployWhiteListAsync(); - rebalancingFactory = await coreHelper.deployRebalancingSetTokenV2FactoryAsync( - coreMock.address, - rebalancingComponentWhiteList.address, - liquidatorWhitelist.address, - feeCalculatorWhitelist.address, - ); - - await coreHelper.setDefaultStateAndAuthorizationsAsync(coreMock, vault, transferProxy, setTokenFactory); - await coreHelper.addFactoryAsync(coreMock, rebalancingFactory); - - component1 = await erc20Helper.deployTokenAsync(deployerAccount); - component2 = await erc20Helper.deployTokenAsync(deployerAccount); - await coreHelper.addTokensToWhiteList( - [component1.address, component2.address], - rebalancingComponentWhiteList, - ); - await erc20Helper.approveTransfersAsync( - [component1, component2], - transferProxy.address - ); - - set1Components = [component1.address, component2.address]; - set1Units = [gWei(1), gWei(1)]; - set1NaturalUnit = gWei(1); - set1 = await coreHelper.createSetTokenAsync( - coreMock, - setTokenFactory.address, - set1Components, - set1Units, - set1NaturalUnit, - ); - - set2Components = [component1.address, component2.address]; - set2Units = [gWei(2), gWei(3)]; - set2NaturalUnit = gWei(2); - set2 = await coreHelper.createSetTokenAsync( - coreMock, - setTokenFactory.address, - set2Components, - set2Units, - set2NaturalUnit, - ); - - component1Price = ether(1); - component2Price = ether(2); - - component1Oracle = await libraryMockHelper.deployUpdatableOracleMockAsync(component1Price); - component2Oracle = await libraryMockHelper.deployUpdatableOracleMockAsync(component2Price); - - oracleWhiteList = await coreHelper.deployOracleWhiteListAsync( - [component1.address, component2.address], - [component1Oracle.address, component2Oracle.address], - ); - - auctionPeriod = ONE_DAY_IN_SECONDS; - rangeStart = new BigNumber(10); // 10% above fair value - rangeEnd = new BigNumber(10); // 10% below fair value - name = 'liquidator'; - - liquidator = await liquidatorHelper.deployLinearAuctionLiquidatorAsync( - coreMock.address, - oracleWhiteList.address, - auctionPeriod, - rangeStart, - rangeEnd, - name, - ); - await coreHelper.addAddressToWhiteList(liquidator.address, liquidatorWhitelist); - - fixedFeeCalculator = await feeCalculatorHelper.deployFixedFeeCalculatorAsync(); - await coreHelper.addAddressToWhiteList(fixedFeeCalculator.address, feeCalculatorWhitelist); - - const currentSetToken = set1; - - setManager = await viewerHelper.deploySocialTradingManagerMockAsync(); - - const failPeriod = ONE_DAY_IN_SECONDS; - const { timestamp } = await web3.eth.getBlock('latest'); - const lastRebalanceTimestamp = new BigNumber(timestamp); - rebalancingSetToken = await rebalancingHelper.createDefaultRebalancingSetTokenV2Async( - coreMock, - rebalancingFactory.address, - setManager.address, - liquidator.address, - feeRecipient, - fixedFeeCalculator.address, - currentSetToken.address, - failPeriod, - lastRebalanceTimestamp, - ); - - const currentAllocation = ether(.6); - await setManager.updateRecord.sendTransactionAsync( - rebalancingSetToken.address, - trader, - allocator, - currentAllocation - ); - - // Issue currentSetToken - await coreMock.issue.sendTransactionAsync( - currentSetToken.address, - ether(8), - {from: deployerAccount} - ); - await erc20Helper.approveTransfersAsync([currentSetToken], transferProxy.address); - - // Use issued currentSetToken to issue rebalancingSetToken - const rebalancingSetQuantityToIssue = ether(7); - await coreMock.issue.sendTransactionAsync(rebalancingSetToken.address, rebalancingSetQuantityToIssue); - - await blockchain.increaseTimeAsync(ONE_DAY_IN_SECONDS); - - - const liquidatorData = '0x'; - nextSet = set2; - newAllocation = ether(.4); - await setManager.rebalance.sendTransactionAsync( - rebalancingSetToken.address, - nextSet.address, - newAllocation, - liquidatorData - ); - - subjectTradingPool = rebalancingSetToken.address; + describe('#fetchNewTradingPoolDetails', async () => { + let subjectTradingPool: Address; + + let newFee: BigNumber; + let feeUpdateTimestamp: BigNumber; + beforeEach(async () => { + newFee = ether(.02); + await setManager.updateFee.sendTransactionAsync( + rebalancingSetToken.address, + newFee + ); + + const { timestamp } = await web3.eth.getBlock('latest'); + feeUpdateTimestamp = new BigNumber(timestamp); + + subjectTradingPool = rebalancingSetToken.address; + }); + + async function subject(): Promise { + return protocolViewer.fetchNewTradingPoolDetails.callAsync( + subjectTradingPool + ); + } + + it('fetches the correct poolInfo data', async () => { + const [ poolInfo, , ] = await subject(); + + expect(poolInfo.trader).to.equal(trader); + expect(poolInfo.allocator).to.equal(allocator); + expect(poolInfo.currentAllocation).to.be.bignumber.equal(currentAllocation); + expect(poolInfo.newEntryFee).to.be.bignumber.equal(newFee); + expect(poolInfo.feeUpdateTimestamp).to.be.bignumber.equal(feeUpdateTimestamp); + }); + + it('fetches the correct RebalancingSetTokenV2/TradingPool data', async () => { + const [ , rbSetData, ] = await subject(); + + expect(rbSetData.manager).to.equal(setManager.address); + expect(rbSetData.feeRecipient).to.equal(feeRecipient); + expect(rbSetData.currentSet).to.equal(currentSetToken.address); + expect(rbSetData.name).to.equal('Rebalancing Set Token'); + expect(rbSetData.symbol).to.equal('RBSET'); + expect(rbSetData.unitShares).to.be.bignumber.equal(DEFAULT_UNIT_SHARES); + expect(rbSetData.naturalUnit).to.be.bignumber.equal(DEFAULT_REBALANCING_NATURAL_UNIT); + expect(rbSetData.rebalanceInterval).to.be.bignumber.equal(ONE_DAY_IN_SECONDS); + expect(rbSetData.entryFee).to.be.bignumber.equal(ZERO); + expect(rbSetData.rebalanceFee).to.be.bignumber.equal(ZERO); + expect(rbSetData.lastRebalanceTimestamp).to.be.bignumber.equal(lastRebalanceTimestamp); + expect(rbSetData.rebalanceState).to.be.bignumber.equal(ZERO); + }); + + it('fetches the correct CollateralSet data', async () => { + const [ , , collateralSetData ] = await subject(); + + expect(JSON.stringify(collateralSetData.components)).to.equal(JSON.stringify(set1Components)); + expect(JSON.stringify(collateralSetData.units)).to.equal(JSON.stringify(set1Units)); + expect(collateralSetData.naturalUnit).to.be.bignumber.equal(set1NaturalUnit); + expect(collateralSetData.name).to.equal('Set Token'); + expect(collateralSetData.symbol).to.equal('SET'); + }); }); - async function subject(): Promise { - return protocolViewer.fetchTradingPoolRebalanceDetails.callAsync( - subjectTradingPool - ); - } - - it('fetches the correct poolInfo data', async () => { - const [ poolInfo, , ] = await subject(); - - expect(poolInfo.trader).to.equal(trader); - expect(poolInfo.allocator).to.equal(allocator); - expect(poolInfo.currentAllocation).to.be.bignumber.equal(newAllocation); + describe('#fetchTradingPoolRebalanceDetails', async () => { + let subjectTradingPool: Address; + + let set2: SetTokenContract; + let set2Components: Address[]; + let set2Units: BigNumber[]; + let set2NaturalUnit: BigNumber; + + let newAllocation: BigNumber; + let nextSet: SetTokenContract; + + beforeEach(async () => { + set2Components = [component1.address, component2.address]; + set2Units = [gWei(2), gWei(3)]; + set2NaturalUnit = gWei(2); + set2 = await coreHelper.createSetTokenAsync( + coreMock, + setTokenFactory.address, + set2Components, + set2Units, + set2NaturalUnit, + ); + + // Issue currentSetToken + await coreMock.issue.sendTransactionAsync( + currentSetToken.address, + ether(8), + {from: deployerAccount} + ); + await erc20Helper.approveTransfersAsync([currentSetToken], transferProxy.address); + + // Use issued currentSetToken to issue rebalancingSetToken + const rebalancingSetQuantityToIssue = ether(7); + await coreMock.issue.sendTransactionAsync(rebalancingSetToken.address, rebalancingSetQuantityToIssue); + + await blockchain.increaseTimeAsync(ONE_DAY_IN_SECONDS); + + + const liquidatorData = '0x'; + nextSet = set2; + newAllocation = ether(.4); + await setManager.rebalance.sendTransactionAsync( + rebalancingSetToken.address, + nextSet.address, + newAllocation, + liquidatorData + ); + + subjectTradingPool = rebalancingSetToken.address; + }); + + async function subject(): Promise { + return protocolViewer.fetchTradingPoolRebalanceDetails.callAsync( + subjectTradingPool + ); + } + + it('fetches the correct poolInfo data', async () => { + const [ poolInfo, , ] = await subject(); + + expect(poolInfo.trader).to.equal(trader); + expect(poolInfo.allocator).to.equal(allocator); + expect(poolInfo.currentAllocation).to.be.bignumber.equal(newAllocation); + expect(poolInfo.newEntryFee).to.be.bignumber.equal(ZERO); + expect(poolInfo.feeUpdateTimestamp).to.be.bignumber.equal(ZERO); + }); + + it('fetches the correct RebalancingSetTokenV2/TradingPool data', async () => { + const [ , rbSetData, ] = await subject(); + + const auctionPriceParams = await rebalancingSetToken.getAuctionPriceParameters.callAsync(); + const startingCurrentSets = await rebalancingSetToken.startingCurrentSetAmount.callAsync(); + const biddingParams = await rebalancingSetToken.getBiddingParameters.callAsync(); + + expect(rbSetData.rebalanceStartTime).to.be.bignumber.equal(auctionPriceParams[0]); + expect(rbSetData.timeToPivot).to.be.bignumber.equal(auctionPriceParams[1]); + expect(rbSetData.startPrice).to.be.bignumber.equal(auctionPriceParams[2]); + expect(rbSetData.endPrice).to.be.bignumber.equal(auctionPriceParams[3]); + expect(rbSetData.startingCurrentSets).to.be.bignumber.equal(startingCurrentSets); + expect(rbSetData.remainingCurrentSets).to.be.bignumber.equal(biddingParams[1]); + expect(rbSetData.minimumBid).to.be.bignumber.equal(biddingParams[0]); + expect(rbSetData.rebalanceState).to.be.bignumber.equal(new BigNumber(2)); + expect(rbSetData.nextSet).to.equal(nextSet.address); + expect(rbSetData.liquidator).to.equal(liquidator.address); + }); + + it('fetches the correct CollateralSet data', async () => { + const [ , , collateralSetData ] = await subject(); + + expect(JSON.stringify(collateralSetData.components)).to.equal(JSON.stringify(set2Components)); + expect(JSON.stringify(collateralSetData.units)).to.equal(JSON.stringify(set2Units)); + expect(collateralSetData.naturalUnit).to.be.bignumber.equal(set2NaturalUnit); + expect(collateralSetData.name).to.equal('Set Token'); + expect(collateralSetData.symbol).to.equal('SET'); + }); }); - it('fetches the correct RebalancingSetTokenV2/TradingPool data', async () => { - const [ , rbSetData, ] = await subject(); - - const auctionPriceParams = await rebalancingSetToken.getAuctionPriceParameters.callAsync(); - const startingCurrentSets = await rebalancingSetToken.startingCurrentSetAmount.callAsync(); - const biddingParams = await rebalancingSetToken.getBiddingParameters.callAsync(); - - expect(rbSetData.rebalanceStartTime).to.be.bignumber.equal(auctionPriceParams[0]); - expect(rbSetData.timeToPivot).to.be.bignumber.equal(auctionPriceParams[1]); - expect(rbSetData.startPrice).to.be.bignumber.equal(auctionPriceParams[2]); - expect(rbSetData.endPrice).to.be.bignumber.equal(auctionPriceParams[3]); - expect(rbSetData.startingCurrentSets).to.be.bignumber.equal(startingCurrentSets); - expect(rbSetData.remainingCurrentSets).to.be.bignumber.equal(biddingParams[1]); - expect(rbSetData.minimumBid).to.be.bignumber.equal(biddingParams[0]); - expect(rbSetData.rebalanceState).to.be.bignumber.equal(new BigNumber(2)); - expect(rbSetData.nextSet).to.equal(nextSet.address); - expect(rbSetData.liquidator).to.equal(liquidator.address); + describe('#batchFetchTradingPoolEntryFees', async () => { + let subjectTradingPools: Address[]; + + let rebalancingSetToken2: RebalancingSetTokenV2Contract; + let entryFee1: BigNumber; + let entryFee2: BigNumber; + + beforeEach(async () => { + const setManager = await viewerHelper.deploySocialTradingManagerMockAsync(); + + const failPeriod = ONE_DAY_IN_SECONDS; + const { timestamp } = await web3.eth.getBlock('latest'); + const lastRebalanceTimestamp = timestamp; + + entryFee1 = ether(.02); + rebalancingSetToken = await rebalancingHelper.createDefaultRebalancingSetTokenV2Async( + coreMock, + rebalancingFactory.address, + setManager.address, + liquidator.address, + feeRecipient, + fixedFeeCalculator.address, + set1.address, + failPeriod, + new BigNumber(lastRebalanceTimestamp), + entryFee1 + ); + + entryFee2 = ether(.03); + rebalancingSetToken2 = await rebalancingHelper.createDefaultRebalancingSetTokenV2Async( + coreMock, + rebalancingFactory.address, + setManager.address, + liquidator.address, + feeRecipient, + fixedFeeCalculator.address, + set1.address, + failPeriod, + new BigNumber(lastRebalanceTimestamp), + entryFee2 + ); + + subjectTradingPools = [rebalancingSetToken.address, rebalancingSetToken2.address]; + }); + + async function subject(): Promise { + return protocolViewer.batchFetchTradingPoolEntryFees.callAsync( + subjectTradingPools + ); + } + + it('fetches the correct entryFee array', async () => { + const actualEntryFeeArray = await subject(); + + const expectedEntryFeeArray = [entryFee1, entryFee2]; + + expect(JSON.stringify(actualEntryFeeArray)).to.equal(JSON.stringify(expectedEntryFeeArray)); + }); }); - it('fetches the correct CollateralSet data', async () => { - const [ , , collateralSetData ] = await subject(); - - expect(JSON.stringify(collateralSetData.components)).to.equal(JSON.stringify(set2Components)); - expect(JSON.stringify(collateralSetData.units)).to.equal(JSON.stringify(set2Units)); - expect(collateralSetData.naturalUnit).to.be.bignumber.equal(set2NaturalUnit); - expect(collateralSetData.name).to.equal('Set Token'); - expect(collateralSetData.symbol).to.equal('SET'); + describe('#batchFetchTradingPoolRebalanceFees', async () => { + let subjectTradingPools: Address[]; + + let rebalancingSetToken2: RebalancingSetTokenV2Contract; + let rebalanceFee1: BigNumber; + let rebalanceFee2: BigNumber; + + beforeEach(async () => { + const setManager = await viewerHelper.deploySocialTradingManagerMockAsync(); + + const failPeriod = ONE_DAY_IN_SECONDS; + const { timestamp } = await web3.eth.getBlock('latest'); + const lastRebalanceTimestamp = timestamp; + const entryFee = ether(.02); + + rebalanceFee1 = ether(.002); + rebalancingSetToken = await rebalancingHelper.createDefaultRebalancingSetTokenV2Async( + coreMock, + rebalancingFactory.address, + setManager.address, + liquidator.address, + feeRecipient, + fixedFeeCalculator.address, + set1.address, + failPeriod, + new BigNumber(lastRebalanceTimestamp), + entryFee, + rebalanceFee1 + ); + + rebalanceFee2 = ether(.003); + rebalancingSetToken2 = await rebalancingHelper.createDefaultRebalancingSetTokenV2Async( + coreMock, + rebalancingFactory.address, + setManager.address, + liquidator.address, + feeRecipient, + fixedFeeCalculator.address, + set1.address, + failPeriod, + new BigNumber(lastRebalanceTimestamp), + entryFee, + rebalanceFee2 + ); + + subjectTradingPools = [rebalancingSetToken.address, rebalancingSetToken2.address]; + }); + + async function subject(): Promise { + return protocolViewer.batchFetchTradingPoolRebalanceFees.callAsync( + subjectTradingPools + ); + } + + it('fetches the correct rebalanceFee array', async () => { + const actualEntryRebalanceArray = await subject(); + + const expectedEntryRebalanceArray = [rebalanceFee1, rebalanceFee2]; + + expect(JSON.stringify(actualEntryRebalanceArray)).to.equal(JSON.stringify(expectedEntryRebalanceArray)); + }); }); }); }); diff --git a/yarn.lock b/yarn.lock index 15f31d222..93675efa4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6458,6 +6458,33 @@ set-protocol-contracts@^1.2.3: web3 "1.0.0-beta.36" web3-utils "1.0.0-beta.36" +set-protocol-contracts@^1.3.13-beta: + version "1.3.13-beta" + resolved "https://registry.yarnpkg.com/set-protocol-contracts/-/set-protocol-contracts-1.3.13-beta.tgz#85529bbd2620640e91b7541bcbc1fca8d96b7145" + integrity sha512-TefAGIjQ6jkLlV2QQG5KkG81jOaKKyHy3lTGPgLsUrDY4kpUlE5RXW5QOP6pTMmM1km8DO6kdaOzkXpRElBNzA== + dependencies: + bn-chai "^1.0.1" + canonical-weth "^1.3.1" + dotenv "^6.2.0" + eth-gas-reporter "^0.1.10" + ethlint "^1.2.3" + expect "^24.1.0" + fs-extra "^5.0.0" + husky "^0.14.3" + lint-staged "^7.2.0" + module-alias "^2.1.0" + openzeppelin-solidity "^2.2" + set-protocol-strategies "^1.1.22" + set-protocol-utils "^1.0.0-beta.44" + tiny-promisify "^1.0.0" + truffle-flattener "^1.4.0" + ts-mocha "^6.0.0" + ts-node "^8.0.2" + tslint-eslint-rules "^5.3.1" + web3 "1.0.0-beta.36" + web3-utils "1.0.0-beta.36" + zos-lib "^2.4.2" + set-protocol-contracts@^1.3.8-beta: version "1.3.8-beta" resolved "https://registry.yarnpkg.com/set-protocol-contracts/-/set-protocol-contracts-1.3.8-beta.tgz#a632c07fbb8ed9ee74e9627805dc9abcec7f2f4f" @@ -6511,6 +6538,32 @@ set-protocol-strategies@^1.1.22: web3 "1.0.0-beta.36" web3-utils "1.0.0-beta.36" +set-protocol-strategies@^1.1.24: + version "1.1.24" + resolved "https://registry.yarnpkg.com/set-protocol-strategies/-/set-protocol-strategies-1.1.24.tgz#b8cfdc6c47c2a425065065cac32c4d6b98bac2ff" + integrity sha512-cDydbISs8g3KJWKbcZmkwT/hIrlabS5IYiT3w7aMEjo1lhHK8lua0cNNEEkffEIHu3bFhyZikxXC8Vb+K9gGXg== + dependencies: + bn-chai "^1.0.1" + canonical-weth "^1.3.1" + dotenv "^6.2.0" + eth-gas-reporter "^0.1.10" + ethlint "^1.2.3" + expect "^24.1.0" + fs-extra "^5.0.0" + husky "^0.14.3" + lint-staged "^7.2.0" + module-alias "^2.1.0" + openzeppelin-solidity "^2.2" + set-protocol-contracts "^1.3.13-beta" + set-protocol-utils "^1.0.0-beta.45" + tiny-promisify "^1.0.0" + truffle-flattener "^1.4.2" + ts-mocha "^6.0.0" + ts-node "^8.0.2" + tslint-eslint-rules "^5.3.1" + web3 "1.0.0-beta.36" + web3-utils "1.0.0-beta.36" + set-protocol-strategies@^1.1.7: version "1.1.9" resolved "https://registry.yarnpkg.com/set-protocol-strategies/-/set-protocol-strategies-1.1.9.tgz#db6e665904ecdd1a90f85470f3b5a7f9e5c9fdd8"