Skip to content
This repository has been archived by the owner on Jan 14, 2020. It is now read-only.

Commit

Permalink
Mainnet truffle migrations (#563)
Browse files Browse the repository at this point in the history
* Add prod multi-sig wallets to owner whitelist

* Fix broken error message

* Add prod addresses to token transactor whitelist

* Production-only migrations

* Transfers ownership of marketplace & token contracts to multi-sig
  wallets
* Transfers all OGN to token multi-sig wallet
* Verifies state of token & marketplace contracts

Resolves #547

* code review changes
  • Loading branch information
cuongdo authored and franckc committed Sep 27, 2018
1 parent 3a58391 commit 870a1a6
Show file tree
Hide file tree
Showing 6 changed files with 181 additions and 18 deletions.
109 changes: 109 additions & 0 deletions contracts/migrations/10_verify_mainnet.js
@@ -0,0 +1,109 @@
const OriginToken = artifacts.require('./token/OriginToken.sol')
const V00_Marketplace = artifacts.require('./V00_Marketplace.sol')

const tokenMultiSig = '0xe011fa2a6df98c69383457d87a056ed0103aa352'
const marketplaceMultiSig = '0x8a1a4f77f9f0eb35fb9930696038be6220986c1b'

module.exports = function(deployer, network) {
return deployer.then(() => {
if (network === 'mainnet' || process.env['SIMULATE_MAINNET']) {
return verifyMainnetContracts()
}
})
}

async function verifyMainnetContracts() {
await verifyTokenContract()
await verifyMarketplaceContract()
}

async function verifyTokenContract() {
const accounts = await new Promise((resolve, reject) => {
web3.eth.getAccounts((error, result) => {
if (error) {
reject(error)
}
resolve(result)
})
})
const oldOwner = accounts[0]
const token = await OriginToken.deployed()
const marketplace = await V00_Marketplace.deployed()

console.log('Validating token contract')

assertEquals(await token.name(), 'OriginToken', 'name')
assertEquals(await token.decimals(), 18, 'decimals')
assertEquals(await token.symbol(), 'OGN', 'symbol')
assertEquals(
(await token.owner()).toLowerCase(),
tokenMultiSig.toLowerCase(),
'owner'
)
assertEquals(await token.paused(), false, 'not paused')
assertEquals(
await token.callSpenderWhitelist(marketplace.address),
true,
'marketplace whitelisted for approveAndCallWithSender'
)
assertEquals(
await token.allowedTransactors(oldOwner),
false,
'old owner not allowed to transfer tokens'
)
assertEquals(
await token.allowedTransactors(marketplace.address),
true,
'marketplace allowed to transfer tokens'
)
assertEquals(
await token.allowedTransactors(tokenMultiSig),
true,
'multi-sig allowed to transfer tokens'
)
assertEquals(
await token.allowedTransactors('0x7aD0fa0E2380a5e0208B25AC69216Bd7Ff206bF8'),
true,
'other wallet allowed to transfer tokens'
)
assertEquals(
await token.whitelistExpiration(),
Date.parse('28 Feb 2019 00:00:00 PST') / 1000,
'whitelist expires on 2/28/2019'
)
}

async function verifyMarketplaceContract() {
const token = await OriginToken.deployed()
const marketplace = await V00_Marketplace.deployed()

console.log('Validating marketplace contract')

assertEquals(
await marketplace.tokenAddr(),
token.address,
'marketplace tokenAddr points to OriginToken'
)
assertEquals(
await marketplace.owner(),
marketplaceMultiSig,
'marketplace contract owned by multi-sig'
)
assertEquals(
await marketplace.allowedAffiliates(marketplace.address),
false,
'marketplace affiliate whitelist enabled'
)
assertEquals(
await marketplace.allowedAffiliates('0x7aD0fa0E2380a5e0208B25AC69216Bd7Ff206bF8'),
true,
'marketplace affiliate address is whitelisted'
)
}

function assertEquals(got, expected, message) {
if (got != expected) {
throw new Error(`${message}: contract value ${got} != expected ${expected}`)
}
console.log(` * ${message}: pass`)
}
30 changes: 15 additions & 15 deletions contracts/migrations/7_create_token_whitelist.js
Expand Up @@ -5,23 +5,12 @@ const V00_Marketplace = artifacts.require('./V00_Marketplace.sol')
const whitelistExpiration = Date.parse('28 Feb 2019 00:00:00 PST') / 1000

module.exports = function(deployer, network) {
return deployer.then(() => {
switch(network) {
case "rinkeby":
case "ropsten":
return createTokenWhitelistForTestnets(network)

case "mainnet":
console.error('\n\n*** WHITELIST MIGRATION NOT YET IMPLEMENTED FOR MAINNET ***\n\n')
return

default:
console.log(`Skipping whitelist creation for network ${network}`)
}
})
if (network !== 'development' || process.env['SIMULATE_MAINNET']) {
return createTokenWhitelist(network)
}
}

async function createTokenWhitelistForTestnets() {
async function createTokenWhitelist(network) {
const token = await OriginToken.deployed()
const tokenOwner = await token.owner()

Expand All @@ -36,6 +25,17 @@ async function createTokenWhitelistForTestnets() {
await token.addAllowedTransactor(marketplace.address, { from: tokenOwner })
console.log(`Added marketplace ${marketplace.address} to whitelist`)

if (network === 'mainnet' || process.env['SIMULATE_MAINNET']) {
const addresses = [
'0x7aD0fa0E2380a5e0208B25AC69216Bd7Ff206bF8', // affiliate
'0xe011fa2a6df98c69383457d87a056ed0103aa352', // ERC20 multi-sig
]
for (const address of addresses) {
await token.addAllowedTransactor(address, { from: tokenOwner })
console.log(`Added address ${address} to whitelist`)
}
}

// Activate the whitelist.
await token.setWhitelistExpiration(whitelistExpiration, { from: tokenOwner })
console.log(`Enabled token whitelist, expiring at UNIX timestamp ${whitelistExpiration}`)
Expand Down
5 changes: 5 additions & 0 deletions contracts/migrations/8_whitelist_affiliate.js
Expand Up @@ -26,6 +26,11 @@ async function whitelistAffiliate(_, network) {
development: '0x627306090abab3a6e1400e9345bc60c78a8bef57',
mainnet: '0x7aD0fa0E2380a5e0208B25AC69216Bd7Ff206bF8'
}

if (process.env['SIMULATE_MAINNET']) {
console.log('simulating mainnet')
network = 'mainnet'
}
const affiliate = affiliates[network]
if (affiliate) {
console.log(`whitelisting affiliate ${affiliate}`)
Expand Down
@@ -0,0 +1,49 @@
const OriginToken = artifacts.require('./token/OriginToken.sol')
const V00_Marketplace = artifacts.require('./V00_Marketplace.sol')

// TODO: extract these addresses into a common file that can be imported from
// the various places that require these addresses
const tokenMultiSig = '0xe011fa2a6df98c69383457d87a056ed0103aa352'
const marketplaceMultiSig = '0x8a1a4f77f9f0eb35fb9930696038be6220986c1b'

module.exports = function(deployer, network) {
return deployer.then(() => {
if (network === 'mainnet' || process.env['SIMULATE_MAINNET']) {
return transferTokensAndContractsToMultiSig()
}
})
}

async function transferTokensAndContractsToMultiSig() {
const accounts = await new Promise((resolve, reject) => {
web3.eth.getAccounts((error, result) => {
if (error) {
reject(error)
}
resolve(result)
})
})
const owner = accounts[0]
const token = await OriginToken.deployed()

// Transfer all tokens to multi-sig wallet.
const balance = await token.balanceOf(owner)
const decimals = await token.decimals()
await token.transfer(tokenMultiSig, balance, { from: owner })
const balanceTokens = balance / 10**decimals
console.log(`transferred ${balanceTokens} OGN to ${tokenMultiSig}`)

// Contract owner is a throwaway account, so remove it from the transactor
// whitelist.
await token.removeAllowedTransactor(owner, { from: owner })

// Transfer token contract to multi-sig wallet.
await token.transferOwnership(tokenMultiSig, { from: owner })
console.log(`token contract owner set to ${tokenMultiSig}`)

// Transfer marketplace contract to multi-sig wallet.
const marketplace = await V00_Marketplace.deployed()
await marketplace.transferOwnership(marketplaceMultiSig, { from: owner })
console.log(`marketplace contract owner set to ${marketplaceMultiSig}`)
}

2 changes: 1 addition & 1 deletion token/lib/_contractHelper.js
Expand Up @@ -159,7 +159,7 @@ class ContractHelper {
// Ensure that the sender is a signer/owner for the wallet.
const isOwner = await wallet.methods.isOwner(sender).call()
if (!isOwner) {
throw `${from} is not an owner of the multisig wallet`
throw `${sender} is not an owner of the multisig wallet`
}

return wallet.methods.submitTransaction(contractAddress, 0, data)
Expand Down
4 changes: 2 additions & 2 deletions token/lib/owner_whitelist.js
@@ -1,8 +1,8 @@
const validOwners = {
// mainnet
"1": [
// Empty list means allow all
// TODO: fill this in
'0xe011fa2a6df98c69383457d87a056ed0103aa352',
'0x8a1a4f77f9f0eb35fb9930696038be6220986c1b'
],

// Ropsten
Expand Down

0 comments on commit 870a1a6

Please sign in to comment.