Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: gov v3 #564

Merged
merged 41 commits into from
Jan 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
3cdeddd
feat: type generation for new contreacts gov v3
JoaquinBattilana Dec 8, 2023
6e236ad
feat: gov data helpers
grothem Dec 8, 2023
dffafc6
fix: export
grothem Dec 8, 2023
40a6b88
fix: typings
grothem Dec 8, 2023
d87da87
fix: rename
grothem Dec 8, 2023
d78bb15
fix: types
grothem Dec 8, 2023
749ebcf
fix: types
grothem Dec 8, 2023
1b37837
feat: helper methods
grothem Dec 8, 2023
91bcd5a
fix: types
grothem Dec 8, 2023
fda96ff
feat: voting machine data helper
grothem Dec 11, 2023
644ea70
fix: build
grothem Dec 11, 2023
40e2352
feat: gov core
grothem Dec 11, 2023
1433358
fix: export
grothem Dec 11, 2023
d0266e1
feat: update reps
grothem Dec 13, 2023
e8b6223
feat: aave v3 token
grothem Dec 19, 2023
69530bf
fix: specify block number
grothem Dec 19, 2023
ddd2484
feat: payloads data service
grothem Dec 20, 2023
0513918
fix: export
grothem Dec 20, 2023
7ec0959
feat: meta delegation
grothem Dec 21, 2023
7ec04b0
feat: token delegate
grothem Dec 21, 2023
182191f
fix: export
grothem Dec 22, 2023
2022bac
feat: deleted export
JoaquinBattilana Dec 26, 2023
000dc6b
feat: added getPowers
JoaquinBattilana Dec 29, 2023
a36249a
feat: added delegateedata
JoaquinBattilana Dec 31, 2023
98720b3
feat: get eip712 domain
grothem Jan 2, 2024
8760e6b
fix: staked token v3
grothem Jan 2, 2024
666caa6
fix: staking test
grothem Jan 2, 2024
a59b646
fix: staked token types
grothem Jan 3, 2024
83b4ed7
fix: abi
grothem Jan 3, 2024
b6faacd
fix: domain
grothem Jan 3, 2024
40ce955
fix: domain
grothem Jan 3, 2024
5cb0783
fix: domain
grothem Jan 3, 2024
3a3b9e4
fix: message
grothem Jan 3, 2024
297f7e8
fix: test
grothem Jan 3, 2024
d705d88
fix: sig
grothem Jan 3, 2024
c91f1f0
fix: sig
grothem Jan 3, 2024
81a235b
feat: Feat/gov v3 cleanup (#567)
foodaka Jan 3, 2024
26b82bf
fix: gas limits
grothem Jan 3, 2024
680837d
fix: imports
grothem Jan 3, 2024
706cc81
fix: gas limits
grothem Jan 4, 2024
d4472ca
fix: remove empty file
grothem Jan 5, 2024
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
2 changes: 2 additions & 0 deletions packages/contract-helpers/src/commons/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,8 @@ export enum ProtocolAction {
claimRewardsAndStake = 'claimRewardsAndStake',
setUsageAsCollateral = 'setUsageAsCollateral',
withdrawAndSwitch = 'withdrawAndSwitch',
batchMetaDelegate = 'batchMetaDelegate',
updateRepresentatives = 'updateRepresentatives',
}

export enum GovernanceVote {
Expand Down
8 changes: 8 additions & 0 deletions packages/contract-helpers/src/commons/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,14 @@ export const gasLimitRecommendations: GasRecommendationType = {
limit: '1000000',
recommended: '1000000',
},
[ProtocolAction.batchMetaDelegate]: {
limit: '200000',
recommended: '200000',
},
[ProtocolAction.updateRepresentatives]: {
limit: '60000',
recommended: '60000',
},
};

export const mintAmountsPerToken: Record<string, string> = {
Expand Down
84 changes: 84 additions & 0 deletions packages/contract-helpers/src/governance-v3/aave-token-v3/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import { BigNumber, PopulatedTransaction, providers } from 'ethers';
import { AaveTokenV3 } from '../typechain/AaveTokenV3';
import { AaveTokenV3__factory } from '../typechain/factories/AaveTokenV3__factory';

export enum GovernancePowerType {
VOTING,
PROPOSITION,
ALL,
}

interface Eip712Domain {
name: string;
version: string;
chainId: BigNumber;
verifyingContract: string;
}

export class AaveTokenV3Service {
readonly _contract: AaveTokenV3;
readonly _contractInterface = AaveTokenV3__factory.createInterface();

constructor(tokenAddress: string, provider: providers.Provider) {
this._contract = AaveTokenV3__factory.connect(tokenAddress, provider);
}

public async balanceOf(user: string) {
return this._contract.balanceOf(user);
}

public async getPowerAt(
blockNumber: number,
user: string,
delegationType: GovernancePowerType,
) {
return this._contract.functions.getPowerCurrent(user, delegationType, {
blockTag: blockNumber,
});
}

public async getPowers(user: string) {
const powers = await this._contract.getPowersCurrent(user);
return {
votingPower: powers[0],
propositionPower: powers[1],
};
}

public async getDelegateeData(user: string) {
const data = await this._contract.getDelegates(user);
return {
votingDelegatee: data[0],
propositionDelegatee: data[1],
};
}

public getDelegateTxData(
user: string,
delegateTo: string,
type: GovernancePowerType,
): PopulatedTransaction {
const tx: PopulatedTransaction = {};
if (type === GovernancePowerType.ALL) {
tx.data = this._contractInterface.encodeFunctionData('delegate', [
delegateTo,
]);
} else {
tx.data = this._contractInterface.encodeFunctionData('delegateByType', [
delegateTo,
type,
]);
}

return {
...tx,
to: this._contract.address,
from: user,
gasLimit: BigNumber.from('100000'),
};
}

public async getEip712Domain(): Promise<Eip712Domain> {
return this._contract.functions.eip712Domain();
}
}
150 changes: 150 additions & 0 deletions packages/contract-helpers/src/governance-v3/delegate-helper/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
import { BigNumber, PopulatedTransaction, providers } from 'ethers';
import { tEthereumAddress, ENS, ProtocolAction } from '../../commons/types';
import { gasLimitRecommendations } from '../../commons/utils';
import { MetaDelegateHelper } from '../typechain/MetaDelegateHelper';
import { MetaDelegateHelper__factory } from '../typechain/factories/MetaDelegateHelper__factory';
export enum DelegationType {
VOTING,
PROPOSITION,
ALL,
}

export type MetaDelegateParams = {
delegator: string;
delegatee: string;
underlyingAsset: string;
deadline: string;
v: number;
r: string;
s: string;
delegationType: number;
};

export type DelegateMetaSigParams = {
underlyingAsset: tEthereumAddress;
delegatee: tEthereumAddress | ENS;
delegationType: DelegationType;
delegator: tEthereumAddress;
increaseNonce: boolean;
governanceTokenName: string;
nonce: string;
connectedChainId: number;
deadline: string;
};

export class MetaDelegateHelperService {
readonly _contract: MetaDelegateHelper;

readonly _contractInterface = MetaDelegateHelper__factory.createInterface();
private readonly metaDelegateHelperContractAddress: string;

constructor(
metaDelegateHelperContractAddress: string,
provider: providers.Provider,
) {
this.metaDelegateHelperContractAddress = metaDelegateHelperContractAddress; // Assign the contract address

this._contract = MetaDelegateHelper__factory.connect(
metaDelegateHelperContractAddress,
provider,
);
}

public batchMetaDelegate(
user: string,
delegateParams: MetaDelegateParams[],
): PopulatedTransaction {
const tx: PopulatedTransaction = {
data: this._contractInterface.encodeFunctionData('batchMetaDelegate', [
delegateParams,
]),
to: this.metaDelegateHelperContractAddress,
from: user,
gasLimit: BigNumber.from(
gasLimitRecommendations[ProtocolAction.batchMetaDelegate].limit,
),
};
return tx;
}

public async prepareV3DelegateByTypeSignature({
underlyingAsset,
delegatee,
delegationType,
delegator,
increaseNonce,
governanceTokenName,
nonce,
connectedChainId,
deadline,
}: DelegateMetaSigParams): Promise<string> {
const isAllDelegate = delegationType === DelegationType.ALL;

const sigBaseType = [
{ name: 'nonce', type: 'uint256' },
{ name: 'deadline', type: 'uint256' },
];
const sigParametersType = [
{ name: 'delegator', type: 'address' },
{ name: 'delegatee', type: 'address' },
];
const sigDelegationTypeType = [{ name: 'delegationType', type: 'uint8' }];

const typesData = {
delegator,
delegatee,
nonce: BigInt(increaseNonce ? Number(nonce) + 1 : nonce).toString(),
deadline,
};

const eIP712DomainType = {
EIP712Domain: [
{
name: 'name',
type: 'string',
},
{
name: 'version',
type: 'string',
},
{
name: 'chainId',
type: 'uint256',
},
{
name: 'verifyingContract',
type: 'address',
},
],
};

const typeData = {
domain: {
name: governanceTokenName,
version: '2',
chainId: connectedChainId,
verifyingContract: underlyingAsset,
},
types: isAllDelegate
? {
...eIP712DomainType,
Delegate: [...sigParametersType, ...sigBaseType],
}
: {
...eIP712DomainType,

DelegateByType: [
...sigParametersType,
...sigDelegationTypeType,
...sigBaseType,
],
},
primaryType: isAllDelegate ? 'Delegate' : 'DelegateByType',
message: isAllDelegate
? { ...typesData }
: { ...typesData, delegationType },
};

return JSON.stringify(typeData);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { BigNumber, PopulatedTransaction, providers } from 'ethers';
import { ChainId, ProtocolAction } from '../../commons/types';
import { gasLimitRecommendations } from '../../commons/utils';
import {
GovernanceCore,
GovernanceCoreInterface,
} from '../typechain/GovernanceCore';
import { GovernanceCore__factory } from '../typechain/factories/GovernanceCore__factory';

export interface GovernanceCoreServiceInterface {
getProposalCount: () => Promise<number>;
updateRepresentativesForChain: (
user: string,
representatives: Array<{ representative: string; chainId: ChainId }>,
) => PopulatedTransaction;
}
export class GovernanceCoreService implements GovernanceCoreServiceInterface {
private readonly _contractInterface: GovernanceCoreInterface;
private readonly _contractInstance: GovernanceCore;

constructor(
governanceCoreContractAddress: string,
provider: providers.Provider,
) {
this._contractInterface = GovernanceCore__factory.createInterface();
this._contractInstance = GovernanceCore__factory.connect(
governanceCoreContractAddress,
provider,
);
}

public async getProposalCount(): Promise<number> {
const count = await this._contractInstance.getProposalsCount();
return count.toNumber();
}

public updateRepresentativesForChain(
user: string,
representatives: Array<{ representative: string; chainId: ChainId }>,
): PopulatedTransaction {
const actionTx: PopulatedTransaction = {
data: this._contractInterface.encodeFunctionData(
'updateRepresentativesForChain',
[representatives],
),
to: this._contractInstance.address,
from: user,
gasLimit: BigNumber.from(
gasLimitRecommendations[ProtocolAction.updateRepresentatives].limit,
),
};

return actionTx;
}
}
Loading
Loading