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

cEUR ContractKit support #7257

Merged
merged 34 commits into from
Mar 4, 2021
Merged
Show file tree
Hide file tree
Changes from 27 commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
e9cb919
Create BaseExchange, BaseStableTokenWrapper, ExchangeEURWrapper, and …
tkporter Feb 17, 2021
01e9c0a
Compiles, but needs ContractEvent to be removed from ICeloToken.ts
tkporter Feb 18, 2021
5852700
New typechain version to fix generated import issue, kit working well…
tkporter Feb 22, 2021
a0a6951
BaseExchange and BaseStableToken tests
tkporter Feb 22, 2021
caf49db
Working tests
tkporter Feb 22, 2021
2317ae4
lint
tkporter Feb 22, 2021
639dff9
Fix transfer_tests (hopefully)
tkporter Feb 24, 2021
6e38bd0
Fix test
tkporter Feb 24, 2021
4505e97
Merge branch 'master' of github.com:celo-org/celo-monorepo into trevo…
tkporter Feb 24, 2021
c08fefa
cleanup
tkporter Feb 24, 2021
e7d2815
Add exchangeEUR to migration overrides
tkporter Feb 24, 2021
0abe028
remove euro from @celo/base/src/currencies
tkporter Feb 24, 2021
7a176a4
Merge branch 'master' of github.com:celo-org/celo-monorepo into trevo…
tkporter Feb 26, 2021
4615b75
Refactor, move away from base classes
tkporter Mar 1, 2021
2213846
Transfer tests without build issues, continuing refactor though
tkporter Mar 2, 2021
4ab9b02
Continuing transfer test refactor
tkporter Mar 3, 2021
d3d95a6
fix conflict in yarn.lock
tkporter Mar 3, 2021
facad25
Merge branch 'master' of github.com:celo-org/celo-monorepo into trevo…
tkporter Mar 3, 2021
ad0a3ac
Yarn lock fix
tkporter Mar 3, 2021
dbc64fd
fix lint
tkporter Mar 3, 2021
16f3261
SortedOracles remove reportStableTokenEUR
tkporter Mar 3, 2021
021c219
Fix transfer test (hopefully)
tkporter Mar 3, 2021
76bf04e
Merge branch 'master' of github.com:celo-org/celo-monorepo into trevo…
tkporter Mar 3, 2021
32e1c25
Modest changes
tkporter Mar 3, 2021
9e5504d
fix lint
tkporter Mar 3, 2021
78a6040
Fix transfer test
tkporter Mar 3, 2021
7b73b76
Merge branch 'master' of github.com:celo-org/celo-monorepo into trevo…
tkporter Mar 3, 2021
ad9bf88
CeloToken -> CeloTokenType
tkporter Mar 4, 2021
b1932f4
Merge branch 'master' of github.com:celo-org/celo-monorepo into trevo…
tkporter Mar 4, 2021
b11d12e
Merge branch 'master' into trevor/ceur-contractkit-master
tkporter Mar 4, 2021
3d5252a
Merge branch 'master' into trevor/ceur-contractkit-master
mergify[bot] Mar 4, 2021
639686b
Merge branch 'master' into trevor/ceur-contractkit-master
mergify[bot] Mar 4, 2021
bfc2987
Merge branch 'master' into trevor/ceur-contractkit-master
mergify[bot] Mar 4, 2021
0125bed
Merge branch 'master' into trevor/ceur-contractkit-master
mergify[bot] Mar 4, 2021
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
144 changes: 69 additions & 75 deletions packages/celotool/src/e2e-tests/transfer_tests.ts

Large diffs are not rendered by default.

28 changes: 28 additions & 0 deletions packages/dev-utils/src/migration-override.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@
"frozen": false,
"minimumReports": 1
},
"exchangeEUR": {
"frozen": false,
"minimumReports": 1
},
"goldToken": {
"frozen": false
},
Expand Down Expand Up @@ -63,6 +67,30 @@
],
"frozen": false
},
"stableTokenEUR": {
"goldPrice": 1,
"initialBalances": {
"addresses": [
"0x5409ED021D9299bf6814279A6A1411A7e866A631",
"0x6Ecbe1DB9EF729CBe972C83Fb886247691Fb6beb",
"0xE36Ea790bc9d7AB70C55260C66D52b1eca985f84",
"0xE834EC434DABA538cd1b9Fe1582052B880BD7e63"
],
"values": [
"50000000000000000000000",
"50000000000000000000000",
"50000000000000000000000",
"50000000000000000000000"
]
},
"oracles": [
"0x5409ED021D9299bf6814279A6A1411A7e866A631",
"0xE36Ea790bc9d7AB70C55260C66D52b1eca985f84",
"0x06cEf8E666768cC40Cc78CF93d9611019dDcB628",
"0x7457d5E02197480Db681D3fdF256c7acA21bDc12"
],
"frozen": false
},
"validators": {
"commissionUpdateDelay": 3
}
Expand Down
2 changes: 1 addition & 1 deletion packages/protocol/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@
"devDependencies": {
"@celo/flake-tracker": "0.0.1-dev",
"@celo/typescript": "0.0.1",
"@celo/typechain-target-web3-v1-celo": "0.1.0-beta3",
"@celo/typechain-target-web3-v1-celo": "0.2.0",
"@types/bn.js": "^4.11.0",
"@types/chai": "^4.1.3",
"@types/mathjs": "^4.4.1",
Expand Down
9 changes: 8 additions & 1 deletion packages/protocol/scripts/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export const ProxyContracts = [
'ElectionProxy',
'EpochRewardsProxy',
'EscrowProxy',
'ExchangeEURProxy',
'ExchangeProxy',
'FeeCurrencyWhitelistProxy',
'GasPriceMinimumProxy',
Expand All @@ -30,6 +31,7 @@ export const ProxyContracts = [
'RegistryProxy',
'ReserveProxy',
'ReserveSpenderMultiSigProxy',
'StableTokenEURProxy',
'StableTokenProxy',
'SortedOraclesProxy',
]
Expand Down Expand Up @@ -66,9 +68,11 @@ export const CoreContracts = [

// stability
'Exchange',
'ExchangeEUR',
'Reserve',
'ReserveSpenderMultiSig',
'StableToken',
'StableTokenEUR',
'SortedOracles',
]

Expand All @@ -79,6 +83,9 @@ const OtherContracts = [
'Initializable',
'UsingRegistry',
]

const Interfaces = ['ICeloToken', 'IERC20']
tkporter marked this conversation as resolved.
Show resolved Hide resolved

export const ImplContracts = OtherContracts.concat(ProxyContracts).concat(CoreContracts)

// const TruffleTestContracts = ['Ownable'].concat(OtherContracts).concat(CoreContracts)
Expand Down Expand Up @@ -128,7 +135,7 @@ async function generateFilesForContractKit() {
exec(`rm -rf ${CONTRACTKIT_GEN_DIR}`)
const relativePath = path.relative(ROOT_DIR, CONTRACTKIT_GEN_DIR)

const contractKitContracts = CoreContracts.concat('Proxy')
const contractKitContracts = CoreContracts.concat('Proxy').concat(Interfaces)

const globPattern = `${BUILD_DIR}/contracts/@(${contractKitContracts.join('|')}).json`

Expand Down
13 changes: 12 additions & 1 deletion packages/sdk/contractkit/src/base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export enum CeloContract {
EpochRewards = 'EpochRewards',
Escrow = 'Escrow',
Exchange = 'Exchange',
ExchangeEUR = 'ExchangeEUR',
FeeCurrencyWhitelist = 'FeeCurrencyWhitelist',
Freezer = 'Freezer',
GasPriceMinimum = 'GasPriceMinimum',
Expand All @@ -22,13 +23,23 @@ export enum CeloContract {
Reserve = 'Reserve',
SortedOracles = 'SortedOracles',
StableToken = 'StableToken',
StableTokenEUR = 'StableTokenEUR',
TransferWhitelist = 'TransferWhitelist',
Validators = 'Validators',
}

export const ProxyContracts = Object.keys(CeloContract).map((c) => `${c}Proxy`)

export type CeloToken = CeloContract.GoldToken | CeloContract.StableToken
export type StableTokenContract = CeloContract.StableToken | CeloContract.StableTokenEUR

export type ExchangeContract = CeloContract.Exchange | CeloContract.ExchangeEUR

export type CeloTokenContract = StableTokenContract | CeloContract.GoldToken
/**
* Deprecated alias for CeloTokenContract.
* @deprecated Use CeloTokenContract instead
*/
export type CeloToken = CeloTokenContract

export const AllContracts = Object.keys(CeloContract) as CeloContract[]
const AuxiliaryContracts = [
Expand Down
52 changes: 52 additions & 0 deletions packages/sdk/contractkit/src/celo-tokens.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import Web3 from 'web3'
import { CeloContract } from './base'
import { CeloTokenInfo, CeloTokens, StableToken, Token } from './celo-tokens'
import { ContractKit, newKitFromWeb3 } from './kit'

describe('CeloTokens', () => {
let kit: ContractKit
let celoTokens: CeloTokens

beforeEach(() => {
kit = newKitFromWeb3(new Web3('http://localhost:8545'))
celoTokens = kit.celoTokens
})

describe('forEachCeloToken()', () => {
it('returns an object with a key for each celo token and the value from a provided async fn', async () => {
const result = await celoTokens.forEachCeloToken(async (info: CeloTokenInfo) =>
Promise.resolve(info.symbol)
)
for (const [key, value] of Object.entries(result)) {
expect(key).toEqual(value)
}
})

it('returns an object with a key for each celo token and the value from a provided non-async fn', async () => {
const result = await celoTokens.forEachCeloToken(async (info: CeloTokenInfo) => info.symbol)
for (const [key, value] of Object.entries(result)) {
expect(key).toEqual(value)
}
})
})

describe('isStableToken()', () => {
it('returns true if the token is a stable token', () => {
expect(celoTokens.isStableToken(StableToken.cUSD)).toEqual(true)
})

it('returns false if the token is not a stable token', () => {
expect(celoTokens.isStableToken(Token.CELO)).toEqual(false)
})
})

describe('isStableTokenContract()', () => {
it('returns true if the contract is a stable token contract', () => {
expect(celoTokens.isStableTokenContract(CeloContract.StableToken)).toEqual(true)
})

it('returns false if the contract is not a stable token contract', () => {
expect(celoTokens.isStableTokenContract(CeloContract.Exchange)).toEqual(false)
})
})
})
201 changes: 201 additions & 0 deletions packages/sdk/contractkit/src/celo-tokens.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,201 @@
import { BigNumber } from 'bignumber.js'
import { CeloContract, CeloTokenContract, ExchangeContract, StableTokenContract } from './base'
import { ContractKit } from './kit'
import { GoldTokenWrapper } from './wrappers/GoldTokenWrapper'
import { StableTokenWrapper } from './wrappers/StableTokenWrapper'

export enum StableToken {
cUSD = 'cUSD',
cEUR = 'cEUR',
}

export enum Token {
CELO = 'CELO',
}

export type CeloToken = StableToken | Token
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(sorry missed to add the concern, haha)
Basically is the name collision between this type and the one in base (even that we know that the other will be deprecated). This could eventually bring some confusion.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just changed to CeloTokenType


type CeloTokenWrapper = GoldTokenWrapper | StableTokenWrapper

export type EachCeloToken<T> = {
[key in CeloToken]: T
}

export interface CeloTokenInfo {
contract: CeloTokenContract
symbol: CeloToken
}

export interface StableTokenInfo extends CeloTokenInfo {
contract: StableTokenContract
exchangeContract: ExchangeContract
}

/** Basic info for each stable token */
const stableTokenInfos: {
[key in StableToken]: StableTokenInfo
} = {
[StableToken.cUSD]: {
contract: CeloContract.StableToken,
exchangeContract: CeloContract.Exchange,
symbol: StableToken.cUSD,
},
[StableToken.cEUR]: {
contract: CeloContract.StableTokenEUR,
exchangeContract: CeloContract.ExchangeEUR,
symbol: StableToken.cEUR,
},
}

/** Basic info for each supported celo token, including stable tokens */
const celoTokenInfos: {
[key in CeloToken]: CeloTokenInfo
} = {
[Token.CELO]: {
contract: CeloContract.GoldToken,
symbol: Token.CELO,
},
...stableTokenInfos,
}

/**
* A helper class to interact with all Celo tokens, ie CELO and stable tokens
*/
export class CeloTokens {
constructor(readonly kit: ContractKit) {}

/**
* Gets an address's balance for each celo token.
* @param address the address to look up the balances for
* @return a promise resolving to an object containing the address's balance
* for each celo token
*/
balancesOf(address: string): Promise<EachCeloToken<BigNumber>> {
return this.forEachCeloToken(async (info: CeloTokenInfo) => {
const wrapper = await this.kit.contracts.getContract(info.contract)
return wrapper.balanceOf(address)
})
}

/**
* Gets the wrapper for each celo token.
* @return an promise resolving to an object containing the wrapper for each celo token.
*/
getWrappers(): Promise<EachCeloToken<CeloTokenWrapper>> {
return this.forEachCeloToken((info: CeloTokenInfo) =>
this.kit.contracts.getContract(info.contract)
)
}

/**
* Gets the address for each celo token proxy contract.
* @return an promise resolving to an object containing the address for each celo token proxy.
*/
getAddresses(): Promise<EachCeloToken<string>> {
return this.forEachCeloToken((info: CeloTokenInfo) =>
this.kit.registry.addressFor(info.contract)
)
}

/**
* Runs fn for each celo token found in celoTokenInfos, and returns the
* value of each call in an object keyed by the token.
* @param fn the function to be called for each CeloTokenInfo.
* @return an object containing the resolved value the call to fn for each
* celo token.
*/
async forEachCeloToken<T>(
fn: (info: CeloTokenInfo) => T | Promise<T>
): Promise<EachCeloToken<T>> {
const wrapperInfos = await Promise.all(
Object.values(celoTokenInfos).map(async (info: CeloTokenInfo) => {
const fnResult = fn(info)
return {
symbol: info.symbol,
data: fnResult instanceof Promise ? await fnResult : fnResult,
}
})
)
return wrapperInfos.reduce(
(
obj: {
[key in CeloToken]?: T
},
wrapperInfo
) => ({
...obj,
[wrapperInfo.symbol]: wrapperInfo.data,
}),
{}
) as EachCeloToken<T>
}

/**
* Gets the wrapper for a given celo token.
* @param token the token to get the appropriate wrapper for
* @return an promise resolving to the wrapper for the token
*/
getWrapper(token: StableToken): Promise<StableTokenWrapper>
getWrapper(token: CeloToken): Promise<CeloTokenWrapper> {
return this.kit.contracts.getContract(celoTokenInfos[token].contract)
}

/**
* Gets the contract for the provided token
* @param token the token to get the contract of
* @return The contract for the token
*/
getContract(token: StableToken): StableTokenContract
getContract(token: CeloToken): CeloTokenContract {
return celoTokenInfos[token].contract
}

/**
* Gets the exchange contract for the provided stable token
* @param token the stable token to get exchange contract of
* @return The exchange contract for the token
*/
getExchangeContract(token: StableToken) {
return stableTokenInfos[token].exchangeContract
}

/**
* Gets the address of the contract for the provided token.
* @param token the token to get the (proxy) contract address for
* @return A promise resolving to the address of the token's contract
*/
getAddress(token: CeloToken) {
return this.kit.registry.addressFor(celoTokenInfos[token].contract)
}

/**
* Gets the address to use as the feeCurrency when paying for gas with the
* provided token.
* @param token the token to get the feeCurrency address for
* @return If not CELO, the address of the token's contract. If CELO, undefined.
*/
getFeeCurrencyAddress(token: CeloToken) {
if (token === Token.CELO) {
return undefined
}
return this.getAddress(token)
}

/**
* Returns if the provided token is a StableToken
* @param token the token
* @return if token is a StableToken
*/
isStableToken(token: CeloToken) {
// We cast token as StableToken to make typescript happy
return Object.values(StableToken).includes(token as StableToken)
}

isStableTokenContract(contract: CeloContract) {
const allStableTokenContracts = Object.values(StableToken).map(
(token) => stableTokenInfos[token].contract
)
// We cast token as StableTokenContract to make typescript happy
return allStableTokenContracts.includes(contract as StableTokenContract)
}
}
2 changes: 2 additions & 0 deletions packages/sdk/contractkit/src/contract-cache.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ import { newKitFromWeb3 } from './kit'
const TestedWrappers: ValidWrappers[] = [
CeloContract.GoldToken,
CeloContract.StableToken,
CeloContract.StableTokenEUR,
CeloContract.Exchange,
CeloContract.ExchangeEUR,
CeloContract.Validators,
CeloContract.LockedGold,
]
Expand Down
Loading