Skip to content

Commit cf9d4a8

Browse files
committed
test: re-add veBal tests, update blockNum
1 parent c86a04c commit cf9d4a8

7 files changed

+789
-2
lines changed

.circleci/config.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ jobs:
9898
e2e-test:
9999
working_directory: ~/repo
100100
executor: nodeimage
101-
parallelism: 7
101+
parallelism: 12
102102
steps:
103103
- attach_workspace:
104104
at: ./

block.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
15719111
1+
15732824
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
import { VeBalHelper } from '@custom-types/contracts';
2+
import { NamedAddresses, NamedContracts } from '@custom-types/types';
3+
import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers';
4+
import { ProposalsConfig } from '@protocol/proposalsConfig';
5+
import { getAddresses, getImpersonatedSigner, time } from '@test/helpers';
6+
import { TestEndtoEndCoordinator } from '@test/integration/setup';
7+
import chai, { expect } from 'chai';
8+
import CBN from 'chai-bn';
9+
import { solidity } from 'ethereum-waffle';
10+
import { BigNumberish, Contract, Signer } from 'ethers';
11+
import { ethers } from 'hardhat';
12+
import { forceEth } from '../setup/utils';
13+
14+
const e18 = (x: BigNumberish) => ethers.constants.WeiPerEther.mul(x);
15+
16+
before(async () => {
17+
chai.use(CBN(ethers.BigNumber));
18+
chai.use(solidity);
19+
});
20+
21+
describe('e2e-veBalHelper-assetManagement', function () {
22+
const impersonatedSigners: { [key: string]: Signer } = {};
23+
let contracts: NamedContracts;
24+
let contractAddresses: NamedAddresses;
25+
let deployAddress: string;
26+
let e2eCoord: TestEndtoEndCoordinator;
27+
let doLogging: boolean;
28+
let vebalOtcHelper: Contract;
29+
let otcBuyerAddress: string;
30+
let otcBuyerSigner: SignerWithAddress;
31+
32+
let balWethBPTWhaleSigner: SignerWithAddress;
33+
const balWethBPTWhale = '0xC128a9954e6c874eA3d62ce62B468bA073093F25';
34+
35+
before(async function () {
36+
deployAddress = (await ethers.getSigners())[0].address;
37+
if (!deployAddress) throw new Error(`No deploy address!`);
38+
const addresses = await getAddresses();
39+
// add any addresses you want to impersonate here
40+
const impersonatedAddresses = [addresses.userAddress, addresses.pcvControllerAddress, addresses.governorAddress];
41+
42+
doLogging = Boolean(process.env.LOGGING);
43+
44+
const config = {
45+
logging: doLogging,
46+
deployAddress: deployAddress,
47+
version: 1
48+
};
49+
50+
e2eCoord = new TestEndtoEndCoordinator(config, ProposalsConfig);
51+
52+
doLogging && console.log(`Loading environment...`);
53+
({ contracts, contractAddresses } = await e2eCoord.loadEnvironment());
54+
55+
({ vebalOtcHelper } = contracts);
56+
doLogging && console.log(`Environment loaded.`);
57+
vebalOtcHelper = vebalOtcHelper as VeBalHelper;
58+
59+
for (const address of impersonatedAddresses) {
60+
impersonatedSigners[address] = await getImpersonatedSigner(address);
61+
}
62+
63+
otcBuyerAddress = contractAddresses.aaveCompaniesMultisig;
64+
await forceEth(otcBuyerAddress);
65+
otcBuyerSigner = await getImpersonatedSigner(otcBuyerAddress);
66+
67+
balWethBPTWhaleSigner = await getImpersonatedSigner(balWethBPTWhale);
68+
await forceEth(balWethBPTWhale);
69+
});
70+
71+
// Tests withdrawERC20() from pcvDeposit
72+
it('should be able to withdrawERC20() to receive B-80BAL-20WETH at end of lock', async () => {
73+
await time.increase(3600 * 24 * 365);
74+
await vebalOtcHelper.connect(otcBuyerSigner).exitLock();
75+
76+
// Can withdrawERC20() to receive B-80BAL-20WETH at end of lock
77+
const bpt80Bal20WethAmount = await contracts.bpt80Bal20Weth.balanceOf(contractAddresses.veBalDelegatorPCVDeposit);
78+
await vebalOtcHelper
79+
.connect(otcBuyerSigner)
80+
.withdrawERC20(contractAddresses.bpt80Bal20Weth, otcBuyerAddress, bpt80Bal20WethAmount);
81+
expect(await contracts.bpt80Bal20Weth.balanceOf(otcBuyerAddress)).to.be.equal(bpt80Bal20WethAmount);
82+
expect(bpt80Bal20WethAmount).to.be.at.least(e18(112_041));
83+
});
84+
85+
// Tests withdrawERC20() from staker
86+
it('can withdrawERC20 from staker', async () => {
87+
await forceEth(balWethBPTWhale);
88+
89+
// Transfer 1 balWETHBPT token to the balancerGaugeStaker, which we will later withdraw
90+
// via the vebalOtcHelper contract
91+
await contracts.balWethBPT.connect(balWethBPTWhaleSigner).transfer(contracts.balancerGaugeStaker.address, 1);
92+
await forceEth(contracts.balancerGaugeStaker.address);
93+
94+
const userBalanceBefore = await contracts.balWethBPT.balanceOf(otcBuyerAddress);
95+
96+
// Withdraw the 1 BPT token from the balancerGaugeStaker to the user
97+
await contracts.vebalOtcHelper
98+
.connect(otcBuyerSigner)
99+
.withdrawERC20fromStaker(contracts.balWethBPT.address, otcBuyerAddress, 1);
100+
101+
const userBalanceAfter = await contracts.balWethBPT.balanceOf(otcBuyerAddress);
102+
expect(userBalanceAfter).to.be.eq(userBalanceBefore.add(1));
103+
});
104+
105+
it('can withdrawETH from pcvDeposit', async () => {
106+
// Transfer 1 ETH to the veBalPCVDeposit
107+
await forceEth(contractAddresses.veBalDelegatorPCVDeposit);
108+
const oneEth = ethers.utils.parseEther('1');
109+
110+
const receiverAddress = '0x0000000000000000000000000000000000000001';
111+
const userEthBefore = await ethers.provider.getBalance(receiverAddress);
112+
113+
// Withdraw ETH from pcvDeposit to the user
114+
await vebalOtcHelper.connect(otcBuyerSigner).withdrawETH(receiverAddress, oneEth);
115+
116+
const userEthAfter = await ethers.provider.getBalance(receiverAddress);
117+
expect(userEthAfter.sub(userEthBefore)).to.equal(oneEth);
118+
});
119+
120+
it('can withdrawETH from staker', async () => {
121+
// Transfer 1 ETH to the staker
122+
await forceEth(contractAddresses.balancerGaugeStaker);
123+
const oneEth = ethers.utils.parseEther('1');
124+
125+
const receiverAddress = '0x0000000000000000000000000000000000000001';
126+
const userEthBefore = await ethers.provider.getBalance(receiverAddress);
127+
128+
// Withdraw ETH from pcvDeposit to the user
129+
await vebalOtcHelper.connect(otcBuyerSigner).withdrawETHfromStaker(receiverAddress, oneEth);
130+
131+
const userEthAfter = await ethers.provider.getBalance(receiverAddress);
132+
expect(userEthAfter.sub(userEthBefore)).to.equal(oneEth);
133+
});
134+
});
+153
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
import { VeBalHelper } from '@custom-types/contracts';
2+
import { NamedAddresses, NamedContracts } from '@custom-types/types';
3+
import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers';
4+
import { ProposalsConfig } from '@protocol/proposalsConfig';
5+
import { getAddresses, getImpersonatedSigner, time } from '@test/helpers';
6+
import { TestEndtoEndCoordinator } from '@test/integration/setup';
7+
import chai, { expect } from 'chai';
8+
import CBN from 'chai-bn';
9+
import { solidity } from 'ethereum-waffle';
10+
import { Contract, Signer } from 'ethers';
11+
import { ethers } from 'hardhat';
12+
import { forceEth } from '../setup/utils';
13+
14+
before(async () => {
15+
chai.use(CBN(ethers.BigNumber));
16+
chai.use(solidity);
17+
});
18+
19+
describe('e2e-veBalHelper-boost-management', function () {
20+
const impersonatedSigners: { [key: string]: Signer } = {};
21+
let contracts: NamedContracts;
22+
let contractAddresses: NamedAddresses;
23+
let deployAddress: string;
24+
let e2eCoord: TestEndtoEndCoordinator;
25+
let doLogging: boolean;
26+
let vebalOtcHelper: Contract;
27+
let otcBuyerAddress: string;
28+
let otcBuyerSigner: SignerWithAddress;
29+
30+
beforeEach(async function () {
31+
deployAddress = (await ethers.getSigners())[0].address;
32+
if (!deployAddress) throw new Error(`No deploy address!`);
33+
const addresses = await getAddresses();
34+
// add any addresses you want to impersonate here
35+
const impersonatedAddresses = [addresses.userAddress, addresses.pcvControllerAddress, addresses.governorAddress];
36+
37+
doLogging = Boolean(process.env.LOGGING);
38+
39+
const config = {
40+
logging: doLogging,
41+
deployAddress: deployAddress,
42+
version: 1
43+
};
44+
45+
e2eCoord = new TestEndtoEndCoordinator(config, ProposalsConfig);
46+
47+
doLogging && console.log(`Loading environment...`);
48+
({ contracts, contractAddresses } = await e2eCoord.loadEnvironment());
49+
50+
({ vebalOtcHelper } = contracts);
51+
doLogging && console.log(`Environment loaded.`);
52+
vebalOtcHelper = vebalOtcHelper as VeBalHelper;
53+
54+
for (const address of impersonatedAddresses) {
55+
impersonatedSigners[address] = await getImpersonatedSigner(address);
56+
}
57+
58+
otcBuyerAddress = contractAddresses.aaveCompaniesMultisig;
59+
await forceEth(otcBuyerAddress);
60+
otcBuyerSigner = await getImpersonatedSigner(otcBuyerAddress);
61+
});
62+
63+
it('should be able to create_boost() to boost delegation to another address', async () => {
64+
await vebalOtcHelper.connect(otcBuyerSigner).create_boost(
65+
contractAddresses.veBalDelegatorPCVDeposit, // address _delegator
66+
contractAddresses.eswak, // address _receiver
67+
'10000', // int256 _percentage
68+
'1669852800', // uint256 _cancel_time = December 1 2022
69+
'1672272000', // uint256 _expire_time = December 29 2022
70+
'0' // uint256 _id
71+
);
72+
const expectedMinBoost = '70000000000000000000000'; // should be 77.5k with 18 decimals as of 14/09/2022
73+
expect(
74+
await contracts.balancerVotingEscrowDelegation.delegated_boost(contracts.veBalDelegatorPCVDeposit.address)
75+
).to.be.at.least(expectedMinBoost);
76+
expect(await contracts.balancerVotingEscrowDelegation.received_boost(contractAddresses.eswak)).to.be.at.least(
77+
expectedMinBoost
78+
);
79+
80+
// token id is uint256(delegatorAddress << 96 + boostId), and boostId = 0
81+
const tokenId = '0xc4eac760c2c631ee0b064e39888b89158ff808b2000000000000000000000000';
82+
expect(await contracts.balancerVotingEscrowDelegation.token_boost(tokenId)).to.be.at.least(expectedMinBoost);
83+
expect(await contracts.balancerVotingEscrowDelegation.token_expiry(tokenId)).to.equal('1672272000');
84+
expect(await contracts.balancerVotingEscrowDelegation.token_cancel_time(tokenId)).to.equal('1669852800');
85+
});
86+
87+
it('should be able to extend_boost', async () => {
88+
await vebalOtcHelper.connect(otcBuyerSigner).create_boost(
89+
contractAddresses.veBalDelegatorPCVDeposit, // address _delegator
90+
contractAddresses.eswak, // address _receiver
91+
'10000', // int256 _percentage
92+
'1669852800', // uint256 _cancel_time = December 1 2022
93+
'1672272000', // uint256 _expire_time = December 29 2022
94+
'0' // uint256 _id
95+
);
96+
const tokenId = '0xc4eac760c2c631ee0b064e39888b89158ff808b2000000000000000000000000';
97+
98+
await time.increase(86400 * 8);
99+
const boostedExpireTime = '1674998582'; // uint256 _expire_time = Jan 29 2023
100+
// - boostedExpireTime gets rounded down to nearest week
101+
const boostedCancelTime = '1672694348'; // uint256 _cancel_time = Jan 2 2023
102+
103+
// Extend the boost
104+
await vebalOtcHelper.connect(otcBuyerSigner).extend_boost(
105+
tokenId,
106+
'10000', // int256 _percentage
107+
boostedExpireTime,
108+
boostedCancelTime
109+
);
110+
111+
const recordedBoostedExpireTime = await contracts.balancerVotingEscrowDelegation.token_expiry(tokenId);
112+
113+
// Expected boosted expire time rounded down to nearest week
114+
const WEEK = 86400 * 7;
115+
const expectedBoostedExpire = Math.floor(Number(boostedExpireTime) / WEEK) * WEEK;
116+
expect(recordedBoostedExpireTime).to.equal(expectedBoostedExpire);
117+
expect(await contracts.balancerVotingEscrowDelegation.token_cancel_time(tokenId)).to.equal(boostedCancelTime);
118+
});
119+
120+
it('should be able to cancel_boost', async () => {
121+
await vebalOtcHelper.connect(otcBuyerSigner).create_boost(
122+
contractAddresses.veBalDelegatorPCVDeposit, // address _delegator
123+
contractAddresses.eswak, // address _receiver
124+
'10000', // int256 _percentage
125+
'1665432310', // uint256 _cancel_time = October 10 2022
126+
'1676495110', // uint256 _expire_time = February 15 2023
127+
'0' // uint256 _id
128+
);
129+
const tokenId = '0xc4eac760c2c631ee0b064e39888b89158ff808b2000000000000000000000000';
130+
expect(await contracts.balancerVotingEscrowDelegation.token_boost(tokenId)).to.be.at.least('1'); // non-zero check
131+
132+
// Cancel boost - fast forward past cancel time
133+
await time.increase(86400 * 30);
134+
await vebalOtcHelper.connect(otcBuyerSigner).cancel_boost(tokenId);
135+
136+
const balancerTokenBoost = await contracts.balancerVotingEscrowDelegation.token_boost(tokenId);
137+
expect(balancerTokenBoost).to.equal(0);
138+
});
139+
140+
it('should be able to burn a token', async () => {
141+
await vebalOtcHelper.connect(otcBuyerSigner).create_boost(
142+
contractAddresses.veBalDelegatorPCVDeposit, // address _delegator
143+
contractAddresses.veBalDelegatorPCVDeposit, // address _receiver (becomes owner, only owner can burn)
144+
'10000', // int256 _percentage
145+
'1669852800', // uint256 _cancel_time = December 1 2022
146+
'1672272000', // uint256 _expire_time = December 29 2022
147+
'0' // uint256 _id
148+
);
149+
const tokenId = '0xc4eac760c2c631ee0b064e39888b89158ff808b2000000000000000000000000';
150+
// Burn token
151+
await vebalOtcHelper.connect(otcBuyerSigner).burn(tokenId);
152+
});
153+
});

0 commit comments

Comments
 (0)