-
Notifications
You must be signed in to change notification settings - Fork 91
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add in GhoTokenService for totalSupply & facilitator info (#444)
* feat: add in GhoTokenService and getFacilitatorBucket * fix: typo * feat: add in more utils for GhoTokenService
- Loading branch information
Showing
8 changed files
with
2,728 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
150 changes: 150 additions & 0 deletions
150
packages/contract-helpers/src/gho/GhoTokenService.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,150 @@ | ||
import { constants, BigNumber, providers } from 'ethers'; | ||
import { valueToWei } from '../commons/utils'; | ||
import { GhoTokenService } from './GhoTokenService'; | ||
import { GhoToken } from './typechain/GhoToken'; | ||
import { GhoToken__factory } from './typechain/GhoToken__factory'; | ||
import { IGhoToken } from './typechain/IGhoToken'; | ||
|
||
jest.mock('../commons/gasStation', () => { | ||
return { | ||
__esModule: true, | ||
estimateGasByNetwork: jest | ||
.fn() | ||
.mockImplementation(async () => Promise.resolve(BigNumber.from(1))), | ||
estimateGas: jest.fn(async () => Promise.resolve(BigNumber.from(1))), | ||
}; | ||
}); | ||
|
||
// Helper for contract call arguments | ||
const convertToBN = (n: string) => valueToWei(n, 18); | ||
|
||
describe('GhoTokenService', () => { | ||
const GHO_TOKEN_ADDRESS = constants.AddressZero; | ||
const correctProvider: providers.Provider = new providers.JsonRpcProvider(); | ||
|
||
// Mocking | ||
jest | ||
.spyOn(correctProvider, 'getGasPrice') | ||
.mockImplementation(async () => Promise.resolve(BigNumber.from(1))); | ||
|
||
afterEach(() => jest.clearAllMocks()); | ||
|
||
describe('Create new GhoTokenService', () => { | ||
it('Expects to be initialized correctly', () => { | ||
// Create Instance | ||
const instance = new GhoTokenService(correctProvider, GHO_TOKEN_ADDRESS); | ||
|
||
// Assert it | ||
expect(instance).toBeInstanceOf(GhoTokenService); | ||
}); | ||
}); | ||
|
||
describe('totalSupply', () => { | ||
it('should return the total supply of GHO tokens', async () => { | ||
// Create Instance | ||
const contract = new GhoTokenService(correctProvider, GHO_TOKEN_ADDRESS); | ||
|
||
// Setup | ||
const mockTotalSupply = convertToBN('10000000'); // 10M | ||
|
||
// Mock it | ||
const spy = jest.spyOn(GhoToken__factory, 'connect').mockReturnValue({ | ||
totalSupply: async () => Promise.resolve(mockTotalSupply), | ||
} as unknown as GhoToken); | ||
|
||
// Call it | ||
const result = await contract.totalSupply(); | ||
|
||
// Assert it | ||
expect(spy).toHaveBeenCalled(); | ||
expect(spy).toBeCalledTimes(1); | ||
expect(result).toEqual(mockTotalSupply); | ||
}); | ||
}); | ||
|
||
describe('getFacilitatorsList', () => { | ||
it('should return the list of facilitators as an array of addresses', async () => { | ||
// Create instance | ||
const contract = new GhoTokenService(correctProvider, GHO_TOKEN_ADDRESS); | ||
|
||
// Setup | ||
const faciliatorAddress1: string = constants.AddressZero; | ||
const faciliatorAddress2: string = constants.AddressZero; | ||
const mockFacilitatorsList: string[] = [ | ||
faciliatorAddress1, | ||
faciliatorAddress2, | ||
]; | ||
|
||
// Mock it | ||
const spy = jest.spyOn(GhoToken__factory, 'connect').mockReturnValue({ | ||
getFacilitatorsList: async () => Promise.resolve(mockFacilitatorsList), | ||
} as unknown as GhoToken); | ||
|
||
// Call it | ||
const result = await contract.getFacilitatorsList(); | ||
|
||
// Assert it | ||
expect(spy).toHaveBeenCalled(); | ||
expect(spy).toBeCalledTimes(1); | ||
expect(result).toEqual(mockFacilitatorsList); | ||
}); | ||
}); | ||
|
||
describe('getFacilitator', () => { | ||
it('should return the facilitator instance for the provided facilitator address', async () => { | ||
// Create instance | ||
const contract = new GhoTokenService(correctProvider, GHO_TOKEN_ADDRESS); | ||
|
||
// Setup | ||
const faciliatorAddress: string = constants.AddressZero; | ||
const mockBucket: IGhoToken.BucketStruct = { | ||
maxCapacity: convertToBN('1000'), | ||
level: convertToBN('500'), | ||
}; | ||
const mockFacilitator: IGhoToken.FacilitatorStruct = { | ||
bucket: mockBucket, | ||
label: 'Aave Facilitator', | ||
}; | ||
|
||
// Mock it | ||
const spy = jest.spyOn(GhoToken__factory, 'connect').mockReturnValue({ | ||
getFacilitator: async () => Promise.resolve(mockFacilitator), | ||
} as unknown as GhoToken); | ||
|
||
// Call it | ||
const result = await contract.getFacilitator(faciliatorAddress); | ||
|
||
// Assert it | ||
expect(spy).toHaveBeenCalled(); | ||
expect(spy).toBeCalledTimes(1); | ||
expect(result).toEqual(mockFacilitator); | ||
}); | ||
}); | ||
|
||
describe('getFacilitatorBucket', () => { | ||
it('should return the bucket instance for the provided facilitator address', async () => { | ||
// Create instance | ||
const contract = new GhoTokenService(correctProvider, GHO_TOKEN_ADDRESS); | ||
|
||
// Setup | ||
const faciliatorAddress: string = constants.AddressZero; | ||
const mockBucket: IGhoToken.BucketStruct = { | ||
maxCapacity: convertToBN('1000'), | ||
level: convertToBN('500'), | ||
}; | ||
|
||
// Mock it | ||
const spy = jest.spyOn(GhoToken__factory, 'connect').mockReturnValue({ | ||
getFacilitatorBucket: async () => Promise.resolve(mockBucket), | ||
} as unknown as GhoToken); | ||
|
||
// Call it | ||
const result = await contract.getFacilitatorBucket(faciliatorAddress); | ||
|
||
// Assert it | ||
expect(spy).toHaveBeenCalled(); | ||
expect(spy).toBeCalledTimes(1); | ||
expect(result).toEqual(mockBucket); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
import { BigNumber, providers } from 'ethers'; | ||
import BaseService from '../commons/BaseService'; | ||
import type { GhoToken } from './typechain/GhoToken'; | ||
import { GhoToken__factory } from './typechain/GhoToken__factory'; | ||
import type { IGhoToken } from './typechain/IGhoToken'; | ||
|
||
interface IGhoTokenService { | ||
totalSupply: () => Promise<BigNumber>; | ||
getFacilitatorsList: () => Promise<string[]>; | ||
getFacilitator: ( | ||
facilitatorAddress: string, | ||
) => Promise<IGhoToken.FacilitatorStruct>; | ||
getFacilitatorBucket: ( | ||
facilitatorAddress: string, | ||
) => Promise<IGhoToken.BucketStruct>; | ||
} | ||
|
||
/** | ||
* The service for interacting with the GhoToken.sol smart contract. | ||
* This contract controls operations minting & burning the native GHO token as well as facilitator management. | ||
* https://github.com/aave/gho/blob/main/src/contracts/gho/GhoToken.sol | ||
*/ | ||
export class GhoTokenService | ||
extends BaseService<GhoToken> | ||
implements IGhoTokenService | ||
{ | ||
readonly ghoTokenAddress: string; | ||
|
||
constructor(provider: providers.Provider, ghoTokenAddress: string) { | ||
super(provider, GhoToken__factory); | ||
this.ghoTokenAddress = ghoTokenAddress; | ||
} | ||
|
||
/** | ||
* Gets the total supply for the GHO token. This is the sum of all facilitators' current bucket levels | ||
* @returns - A BigNumber representing the total supply of GHO | ||
*/ | ||
public async totalSupply() { | ||
const contract = this.getContractInstance(this.ghoTokenAddress); | ||
const result = await contract.totalSupply(); | ||
return result; | ||
} | ||
|
||
/** | ||
* Gets the full list of facilitators for the GHO token | ||
* @returns - An array of facilitator addresses, which can be used for querying in more detail | ||
*/ | ||
public async getFacilitatorsList() { | ||
const contract = this.getContractInstance(this.ghoTokenAddress); | ||
const result = await contract.getFacilitatorsList(); | ||
return result; | ||
} | ||
|
||
/** | ||
* Gets the instance for a given facilitator | ||
* @param facilitatorAddress - The address for the currently deployed contract for the facilitator being queried | ||
* @returns - The instance of the facilitator, which contains `bucket` and `label` fields | ||
*/ | ||
public async getFacilitator(facilitatorAddress: string) { | ||
const contract = this.getContractInstance(this.ghoTokenAddress); | ||
const result = await contract.getFacilitator(facilitatorAddress); | ||
return result; | ||
} | ||
|
||
/** | ||
* Gets the bucket instance for a given facilitator | ||
* @param facilitatorAddress - The address for the currently deployed contract for the facilitator being queried | ||
* @returns - The instance of the facilitator bucket, which contains `maxCapacity` and `level` fields | ||
*/ | ||
public async getFacilitatorBucket(facilitatorAddress: string) { | ||
const contract = this.getContractInstance(this.ghoTokenAddress); | ||
const result = await contract.getFacilitatorBucket(facilitatorAddress); | ||
return result; | ||
} | ||
} |
Oops, something went wrong.