Skip to content

Commit

Permalink
Create StableToken registry (#9346)
Browse files Browse the repository at this point in the history
* initial contract creation

* added a contructor and a mapping

* added function that add fiat tickers into the collection

* function that returns all the fiat symbols thats been issued

* quering a stable contract functionality

* function to retrieve all the contract instances from a mapping

* removing unnecessary imports

* function that returns all the contracts

* added comments

* removed unnecessary function

* removed unnecessary function

* functionality to remove unsupported tokens

* function that adds new instances to the registry

* poor indentation

* resolving bugs

* suggested improvements

* writing initialize

* updated inconsistent syntax

* initialize function is implemented

* some of the resolved compile errors

* resolving compiler issues

* last of compiler issues

* upgrading removeStableToken funrction

* updated registry

* updated initialize function

* removed commented out code

* updated comments

* created a proxy

* updating build file

* updated build file

* initialize test suit

* updating registry contract

* first few tests are passing

* remove stableToken function

* resolving a mistake

* resolving based on corrections

* tests for remove function complete

* test suit for adding contracts

* tests pass

* adding more arguments to compare

* adding registry contract to the registry

* registry migrations

* unsaved changes

* bug fixed in initialized and two more found it addnewstabletoken

* refactoring get contracts function

* converted to bytes and contract compiles

* initialize function added to tests

* 8 tests pass, refactoring the contract

* latest

* fixing bugs

* everything works ✨

* added a contraxt query function + tests

* lists all the correct contract namea after adding and removing one ✨😭

* all functions are fully tested and work

* adding it to the registry

* finished

* fixed migrations

* amount of arguments in initialize error fixed

* bug

* had an accidental type in reserve

* migration tests pass

* one minor fix needed

* removed from registry

* readded in registry-utils

* upgraded the number of migration file the tests should run to

* cleaning up

* applying suggestions

* error in ts wrapper

* fixed migration error

* initial contract creation

* added a contructor and a mapping

* added function that add fiat tickers into the collection

* function that returns all the fiat symbols thats been issued

* quering a stable contract functionality

* function to retrieve all the contract instances from a mapping

* removing unnecessary imports

* function that returns all the contracts

* added comments

* removed unnecessary function

* removed unnecessary function

* functionality to remove unsupported tokens

* function that adds new instances to the registry

* poor indentation

* resolving bugs

* suggested improvements

* writing initialize

* updated inconsistent syntax

* initialize function is implemented

* some of the resolved compile errors

* resolving compiler issues

* last of compiler issues

* upgrading removeStableToken funrction

* updated registry

* updated initialize function

* removed commented out code

* updated comments

* created a proxy

* updating build file

* updated build file

* initialize test suit

* updating registry contract

* first few tests are passing

* remove stableToken function

* resolving a mistake

* resolving based on corrections

* tests for remove function complete

* test suit for adding contracts

* tests pass

* adding more arguments to compare

* adding registry contract to the registry

* registry migrations

* unsaved changes

* bug fixed in initialized and two more found it addnewstabletoken

* refactoring get contracts function

* converted to bytes and contract compiles

* initialize function added to tests

* 8 tests pass, refactoring the contract

* latest

* fixing bugs

* everything works ✨

* added a contraxt query function + tests

* lists all the correct contract namea after adding and removing one ✨😭

* all functions are fully tested and work

* adding it to the registry

* finished

* fixed migrations

* amount of arguments in initialize error fixed

* bug

* had an accidental type in reserve

* migration tests pass

* one minor fix needed

* removed from registry

* readded in registry-utils

* upgraded the number of migration file the tests should run to

* cleaning up

* applying suggestions

* error in ts wrapper

* fixed migration error

* added an empty object in release9

* release tag update

* updating correct release tag

* removed unnecessary release9 json file

* updating the release tag

* add release report

* update the path for ci

* correct ci path

* removed incorrect configs

* Trying to get all the tags from git

* try to add on devchain

* Fixed branch name

* Restored a missing test (#9460)

Authored-by: Nina Barbakadze <ninabarbakadze@macbook-pro-4.localdomain>

* Consistent code across GrandaMento and Exchange in setSpread (#9459)

* Fix Oracle check (#9527)

* Add version report

* Added newline at the end

* Fixed release versions

* Deleted wrong files

* adding a version number

* updated the major version number to 1

* Create release8.json

* Update release8.json

* Update release8.json

* Update release8.json

* Update StableTokenRegistry.sol

Co-authored-by: Nina Barbakadze <ninabarbakadze@macbook-pro-4.localdomain>
Co-authored-by: Nina Barbakadze <ninabarbakadze@MacBook-Pro-4.local>
Co-authored-by: Nina Barbakadze <ninabarbakadze@vd47kwk70w.localdomain>
Co-authored-by: Martín Volpe <volpe@clabs.co>
Co-authored-by: Martin Volpe <martin.volpe@gmail.com>
Co-authored-by: Marcin Chrzanowski <martin@clabs.co>
  • Loading branch information
7 people authored Jul 5, 2022
1 parent c7b995d commit 5d53d92
Show file tree
Hide file tree
Showing 18 changed files with 390 additions and 9 deletions.
3 changes: 2 additions & 1 deletion .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ defaults: &defaults
contract-defaults: &contract-defaults
<<: *defaults
environment:
RELEASE_TAG: core-contracts.v6
RELEASE_TAG: core-contracts.v7

e2e-defaults: &e2e-defaults
<<: *defaults
Expand Down Expand Up @@ -151,6 +151,7 @@ jobs:
# Verify that following commands work, they are later called in the incremental testing script
# There output does not matter here, the fact that they finish successfully does.
git rev-parse --abbrev-ref HEAD
git fetch --all --tags
- attach_workspace:
at: ~/app
Expand Down
2 changes: 1 addition & 1 deletion packages/cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
"generate:shrinkwrap": "npm install --production && npm shrinkwrap",
"check:shrinkwrap": "npm install --production && npm shrinkwrap && ./scripts/check_shrinkwrap_dirty.sh",
"prepack": "yarn run build && oclif-dev manifest && oclif-dev readme && yarn run check:shrinkwrap",
"test:reset": "yarn --cwd ../protocol devchain generate-tar .tmp/devchain.tar.gz --migration_override ../dev-utils/src/migration-override.json --upto 25 --release_gold_contracts scripts/truffle/releaseGoldExampleConfigs.json",
"test:reset": "yarn --cwd ../protocol devchain generate-tar .tmp/devchain.tar.gz --migration_override ../dev-utils/src/migration-override.json --upto 26 --release_gold_contracts scripts/truffle/releaseGoldExampleConfigs.json",
"test:livechain": "yarn --cwd ../protocol devchain run-tar .tmp/devchain.tar.gz",
"test": "TZ=UTC jest --runInBand"
},
Expand Down
125 changes: 125 additions & 0 deletions packages/protocol/contracts/stability/StableTokenRegistry.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
pragma solidity ^0.5.13;

import "openzeppelin-solidity/contracts/math/SafeMath.sol";
import "../common/Initializable.sol";
import "openzeppelin-solidity/contracts/ownership/Ownable.sol";
import "../common/interfaces/IRegistry.sol";

/**
* @title contract that lists what stable coins are deployed as part of Celo's Stability protocol.
*/
contract StableTokenRegistry is Initializable, Ownable {
using SafeMath for uint256;
mapping(bytes => bytes) public stableTokens;
bytes[] public fiatTickers;

/**
* @notice Returns the storage, major, minor, and patch version of the contract.
* @return The storage, major, minor, and patch version of the contract.
*/
function getVersionNumber() external pure returns (uint256, uint256, uint256, uint256) {
return (1, 1, 0, 0);
}

/**
* @notice Sets initialized == true on implementation contracts
* @param test Set to true to skip implementation initialization
*/
constructor(bool test) public Initializable(test) {}

/**
* @notice Used in place of the constructor to allow the contract to be upgradable via proxy.
* @param fiatTicker fiat currency issued.
* @param stableTokenContractName stable token smart contract name.
*/
function initialize(bytes calldata fiatTicker, bytes calldata stableTokenContractName)
external
initializer
{
_transferOwnership(msg.sender);
addNewStableToken(bytes("USD"), bytes("StableToken"));
addNewStableToken(bytes("EUR"), bytes("StableTokenEUR"));
addNewStableToken(bytes("BRL"), bytes("StableTokenBRL"));
if (fiatTicker.length != 0 && stableTokenContractName.length != 0) {
addNewStableToken(fiatTicker, stableTokenContractName);
}
}

/**
* @notice Returns all the contract instances created.
* @return collection of stable token contracts.
*/
function getContractInstances() external view returns (bytes memory, uint256[] memory) {
uint256 totalLength = 0;
for (uint256 i = 0; i < fiatTickers.length; i++) {
totalLength += stableTokens[fiatTickers[i]].length;
}
uint256 numOfContracts = fiatTickers.length;
bytes memory concatenated = new bytes(totalLength);
uint256 lastIndex = 0;
uint256[] memory lengths = new uint256[](numOfContracts);
for (uint256 i = 0; i < numOfContracts; i++) {
bytes storage contractName = stableTokens[fiatTickers[i]];
lengths[i] = contractName.length;
for (uint256 j = 0; j < lengths[i]; j++) {
concatenated[lastIndex] = contractName[j];
lastIndex++;
}
}
return (concatenated, lengths);
}

/**
* @notice Removes unwamted token instances.
* @param fiatTicker The currency that is no longer supported.
* @param index The index in fiatTickers of fiatTicker.
*/
function removeStableToken(bytes calldata fiatTicker, uint256 index) external onlyOwner {
delete stableTokens[fiatTicker];
uint256 numFiats = fiatTickers.length;
require(index < numFiats, "Index is invalid");
for (uint256 i = 0; i < fiatTicker.length; i++) {
if (fiatTicker[i] != 0) {
require(
fiatTicker[i] == fiatTickers[index][i],
"source doesn't match the existing fiatTicker"
);
}
}
uint256 newNumFiats = numFiats.sub(1);

if (index != newNumFiats) {
fiatTickers[index] = fiatTickers[newNumFiats];
}
delete fiatTickers[newNumFiats];
fiatTickers.length = newNumFiats;
}

/**
* @notice Adds new Fiat Ticker and Stable Token contract to the registry.
* @param fiatTicker The currency we are trying to add in the registry.
* @param stableTokenContractName The contract we are trying to add in the registry.
*/
function addNewStableToken(bytes memory fiatTicker, bytes memory stableTokenContractName)
public
onlyOwner
{
require(fiatTicker.length != 0, "fiatTicker cant be an empty string");
require(stableTokenContractName.length != 0, "stableTokenContractName cant be an empty string");
require(stableTokens[fiatTicker].length == 0, "This registry already exists");
stableTokens[fiatTicker] = stableTokenContractName;
fiatTickers.push(fiatTicker);
}

/**
* @notice Queries a corresponding StableToken contract name based on fiat ticker.
* @param fiatTicker Type of currency to query corresponding contract.
*/
function queryStableTokenContractNames(bytes memory fiatTicker)
public
view
returns (bytes memory)
{
return stableTokens[fiatTicker];
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
pragma solidity ^0.5.13;

import "../../common/Proxy.sol";

/* solhint-disable no-empty-blocks */
contract StableTokenRegistryProxy is Proxy {}
1 change: 1 addition & 0 deletions packages/protocol/lib/registry-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ export enum CeloContractName {
StableTokenBRL = 'StableTokenBRL',
TransferWhitelist = 'TransferWhitelist',
Validators = 'Validators',
StableTokenRegistry = 'StableTokenRegistry',
}

export const usesRegistry = [
Expand Down
14 changes: 14 additions & 0 deletions packages/protocol/migrations/25_stableToken_registry.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { CeloContractName } from '@celo/protocol/lib/registry-utils'
import { deploymentForCoreContract } from '@celo/protocol/lib/web3-utils'
import { StableTokenRegistryInstance } from 'types'

const initializeArgs = async (): Promise<any[]> => {
return [[], []]
}

module.exports = deploymentForCoreContract<StableTokenRegistryInstance>(
web3,
artifacts,
CeloContractName.StableTokenRegistry,
initializeArgs
)
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ module.exports = deploymentForCoreContract<GovernanceInstance>(
'StableToken',
'StableTokenEUR',
'Validators',
'StableTokenRegistry',
]

if (!config.governance.skipTransferOwnership) {
Expand Down
4 changes: 4 additions & 0 deletions packages/protocol/migrationsConfig.js
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,10 @@ const DefaultConfig = {
commission: 0.1,
votesRatioOfLastVsFirstGroup: 2.0,
},
stableTokenRegistry: {
fiatTicker: [], // empty array resambles empty bytes
stableTokenContractName: [], // empty array resambles empty bytes
},
}

const NetworkConfigs = {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"StableTokenRegistry": [[], []]
}
67 changes: 65 additions & 2 deletions packages/protocol/releaseData/versionReports/release7-report.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"oldArtifactsFolder": "/Users/martinvol/celo/celo-monorepo/packages/protocol/build/core-contracts.v6/contracts",
"newArtifactsFolder": "/Users/martinvol/celo/celo-monorepo/packages/protocol/build/celo-core-contracts-v7/contracts",
"oldArtifactsFolder": "/home/circleci/app/packages/protocol/build/core-contracts.v6/contracts",
"newArtifactsFolder": "/home/circleci/app/packages/protocol/build/core-contracts.v7/contracts",
"exclude": "/.*Test|Mock.*|I[A-Z].*|.*Proxy|MultiSig.*|ReleaseGold|SlasherUtil|UsingPrecompiles/",
"report": {
"contracts": {
Expand Down Expand Up @@ -147,6 +147,69 @@
"patch": "0"
}
},
"LockedGold": {
"changes": {
"storage": [],
"major": [],
"minor": [
{
"contract": "LockedGold",
"signature": "getPendingWithdrawal(address,uint256)",
"type": "MethodAdded"
}
],
"patch": [
{
"contract": "LockedGold",
"type": "DeployedBytecode"
}
]
},
"versionDelta": {
"storage": "=",
"major": "=",
"minor": "+1",
"patch": "0"
}
},
"GrandaMento": {
"changes": {
"storage": [],
"major": [],
"minor": [],
"patch": [
{
"contract": "GrandaMento",
"type": "DeployedBytecode"
}
]
},
"versionDelta": {
"storage": "=",
"major": "=",
"minor": "=",
"patch": "+1"
}
},
"Reserve": {
"changes": {
"storage": [],
"major": [],
"minor": [],
"patch": [
{
"contract": "Reserve",
"type": "DeployedBytecode"
}
]
},
"versionDelta": {
"storage": "=",
"major": "=",
"minor": "=",
"patch": "+1"
}
},
"Validators": {
"changes": {
"storage": [],
Expand Down
5 changes: 5 additions & 0 deletions packages/protocol/scripts/bash/release-on-devchain.sh
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,14 @@ yarn run truffle exec ./scripts/truffle/verify-bytecode.js --network development

echo "- Check versions of current branch"
# From check-versions.sh
echo " - Checkout migrationsConfig.js at $BRANCH"
git checkout $BRANCH -- migrationsConfig.js

CONTRACT_EXCLUSION_REGEX=".*Test|Mock.*|I[A-Z].*|.*Proxy|MultiSig.*|ReleaseGold|SlasherUtil|UsingPrecompiles"
yarn ts-node scripts/check-backward.ts sem_check --old_contracts $BUILD_DIR/contracts --new_contracts build/contracts --exclude $CONTRACT_EXCLUSION_REGEX --output_file report.json

git checkout - -- migrationsConfig.js

# From make-release.sh
echo "- Deploy release of current branch"
INITIALIZATION_FILE=`ls -1 releaseData/initializationData/* | tail -n 1 | xargs realpath`
Expand Down
2 changes: 2 additions & 0 deletions packages/protocol/scripts/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ export const ProxyContracts = [
'StableTokenEURProxy',
'StableTokenProxy',
'SortedOraclesProxy',
'StableTokenRegistryProxy',
]
export const CoreContracts = [
// common
Expand Down Expand Up @@ -78,6 +79,7 @@ export const CoreContracts = [
'StableTokenEUR',
'StableTokenBRL',
'SortedOracles',
'StableTokenRegistry',

// liquidity
'GrandaMento',
Expand Down
3 changes: 1 addition & 2 deletions packages/protocol/test/common/accounts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { parseSolidityStringArray } from '@celo/utils/lib/parsing'
import { authorizeSigner as buildAuthorizeSignerTypedData } from '@celo/utils/lib/typed-data-constructors'
import { generateTypedDataHash } from '@celo/utils/src/sign-typed-data-utils'
import { parseSignatureWithoutPrefix } from '@celo/utils/src/signatureUtils'
import BigNumber from 'bignumber.js'
import {
AccountsContract,
AccountsInstance,
Expand All @@ -22,8 +23,6 @@ import {
} from 'types'
import { keccak256 } from 'web3-utils'

import BigNumber from 'bignumber.js'

const Accounts: AccountsContract = artifacts.require('Accounts')
const Registry: RegistryContract = artifacts.require('Registry')
const MockValidators: MockValidatorsContract = artifacts.require('MockValidators')
Expand Down
Loading

0 comments on commit 5d53d92

Please sign in to comment.