-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #65 from rsksmart/feature/PP-278/PP-239/PP-438
Deployment Script Hardhat
- Loading branch information
Showing
6 changed files
with
264 additions
and
4 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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
export interface IContractAddresses { | ||
Penalizer: string; | ||
RelayHub: string; | ||
SmartWallet: string; | ||
SmartWalletFactory: string; | ||
SmartWalletDeployVerifier: string; | ||
SmartWalletRelayVerifier: string; | ||
CustomSmartWallet: string; | ||
CustomSmartWalletFactory: string; | ||
CustomSmartWalletDeployVerifier: string; | ||
CustomSmartWalletRelayVerifier: string; | ||
UtilToken: string; | ||
} | ||
export interface IChainContractAddresses { | ||
[key: string]: IContractAddresses | ||
} |
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,108 @@ | ||
import { ethers, hardhatArguments, config } from 'hardhat'; | ||
import fs from 'fs'; | ||
import { | ||
IChainContractAddresses, | ||
IContractAddresses, | ||
} from '../interfaces/contracts'; | ||
|
||
export const generateJsonConfig = (contractAddresses: IContractAddresses) => { | ||
console.log('Generating json config file...'); | ||
|
||
const configFileName = 'contract-addresses.json'; | ||
let jsonConfig: Partial<IChainContractAddresses>; | ||
|
||
if (fs.existsSync(configFileName)) { | ||
jsonConfig = JSON.parse( | ||
fs.readFileSync(configFileName, { encoding: 'utf-8' }) | ||
) as IChainContractAddresses; | ||
} else { | ||
jsonConfig = {}; | ||
} | ||
|
||
const { network } = hardhatArguments; | ||
if (!network) { | ||
throw new Error('Unknown Network'); | ||
} | ||
const { chainId } = config.networks[network]; | ||
|
||
if (!chainId) { | ||
throw new Error('Unknown Chain Id'); | ||
} | ||
|
||
jsonConfig[chainId] = contractAddresses; | ||
|
||
fs.writeFileSync('contract-addresses.json', JSON.stringify(jsonConfig)); | ||
}; | ||
|
||
export const deployContracts = async () => { | ||
const relayHubF = await ethers.getContractFactory('RelayHub'); | ||
const penalizerF = await ethers.getContractFactory('Penalizer'); | ||
const smartWalletF = await ethers.getContractFactory('SmartWallet'); | ||
const smartWalletFactoryF = await ethers.getContractFactory( | ||
'SmartWalletFactory' | ||
); | ||
const deployVerifierF = await ethers.getContractFactory('DeployVerifier'); | ||
const relayVerifierF = await ethers.getContractFactory('RelayVerifier'); | ||
const utilTokenF = await ethers.getContractFactory('UtilToken'); | ||
|
||
const customSmartWalletF = await ethers.getContractFactory( | ||
'CustomSmartWallet' | ||
); | ||
const customSmartWalletFactoryF = await ethers.getContractFactory( | ||
'CustomSmartWalletFactory' | ||
); | ||
const customSmartWalletDeployVerifierF = await ethers.getContractFactory( | ||
'CustomSmartWalletDeployVerifier' | ||
); | ||
|
||
const { address: penalizerAddress } = await penalizerF.deploy(); | ||
const { address: relayHubAddress } = await relayHubF.deploy( | ||
penalizerAddress, | ||
1, | ||
1, | ||
1, | ||
1 | ||
); | ||
const { address: smartWalletAddress } = await smartWalletF.deploy(); | ||
const { address: smartWalletFactoryAddress } = | ||
await smartWalletFactoryF.deploy(smartWalletAddress); | ||
const { address: deployVerifierAddress } = await deployVerifierF.deploy( | ||
smartWalletFactoryAddress | ||
); | ||
const { address: relayVerifierAddress } = await relayVerifierF.deploy( | ||
smartWalletFactoryAddress | ||
); | ||
|
||
const { address: customSmartWalletAddress } = | ||
await customSmartWalletF.deploy(); | ||
const { address: customSmartWalletFactoryAddress } = | ||
await customSmartWalletFactoryF.deploy(customSmartWalletAddress); | ||
const { address: customDeployVerifierAddress } = | ||
await customSmartWalletDeployVerifierF.deploy( | ||
customSmartWalletFactoryAddress | ||
); | ||
|
||
const { address: customRelayVerifierAddress } = await relayVerifierF.deploy( | ||
customSmartWalletFactoryAddress | ||
); | ||
|
||
let utilTokenAddress; | ||
if(hardhatArguments.network != 'mainnet'){ | ||
const { address } = await utilTokenF.deploy(); | ||
utilTokenAddress = address | ||
} | ||
|
||
return { | ||
Penalizer: penalizerAddress, | ||
RelayHub: relayHubAddress, | ||
SmartWallet: smartWalletAddress, | ||
SmartWalletFactory: smartWalletFactoryAddress, | ||
SmartWalletDeployVerifier: deployVerifierAddress, | ||
SmartWalletRelayVerifier: relayVerifierAddress, | ||
CustomSmartWallet: customSmartWalletAddress, | ||
CustomSmartWalletFactory: customSmartWalletFactoryAddress, | ||
CustomSmartWalletDeployVerifier: customDeployVerifierAddress, | ||
CustomSmartWalletRelayVerifier: customRelayVerifierAddress, | ||
UtilToken: utilTokenAddress, | ||
}; | ||
}; |
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,128 @@ | ||
import chai, { expect } from 'chai'; | ||
import chaiAsPromised from 'chai-as-promised'; | ||
import { Contract, ContractFactory } from 'ethers'; | ||
import { ethers } from 'hardhat'; | ||
import sinon from 'sinon'; | ||
import fs from 'fs'; | ||
import * as hardhat from 'hardhat'; | ||
import { | ||
deployContracts, | ||
generateJsonConfig, | ||
} from '../../scripts/modules/deploy'; | ||
|
||
chai.use(chaiAsPromised); | ||
|
||
describe('Deploy Script', function () { | ||
describe('deployContracts', function () { | ||
const testAddress = '0x145845fd06c85B7EA1AA2d030E1a747B3d8d15D7'; | ||
beforeEach(function () { | ||
const contract = new Contract(testAddress, []); | ||
const contractFactoryStub = sinon.createStubInstance(ContractFactory); | ||
sinon.stub(ethers, 'getContractFactory').resolves(contractFactoryStub); | ||
contractFactoryStub.deploy.resolves(contract); | ||
}); | ||
|
||
afterEach(function () { | ||
sinon.restore(); | ||
}); | ||
|
||
it('should deploy all contracts', async function () { | ||
const result = await deployContracts(); | ||
expect(result).to.have.all.keys( | ||
'Penalizer', | ||
'RelayHub', | ||
'SmartWallet', | ||
'SmartWalletFactory', | ||
'SmartWalletDeployVerifier', | ||
'SmartWalletRelayVerifier', | ||
'CustomSmartWallet', | ||
'CustomSmartWalletFactory', | ||
'CustomSmartWalletDeployVerifier', | ||
'CustomSmartWalletRelayVerifier', | ||
'UtilToken' | ||
); | ||
}); | ||
|
||
it('should deploy contracts with valid addresses', async function () { | ||
const result = await deployContracts(); | ||
Object.values(result).forEach((value) => { | ||
expect(value, value).to.eq(testAddress); | ||
}); | ||
}); | ||
|
||
it('should not deploy UtilToken if not in mainnet', async function () { | ||
hardhat.hardhatArguments.network = 'mainnet'; | ||
const result = await deployContracts(); | ||
expect(result.UtilToken).to.be.undefined | ||
}); | ||
}); | ||
|
||
describe('generateJsonConfig', function () { | ||
const contractAddresses = { | ||
Penalizer: '0x145845fd06c85B7EA1AA2d030E1a747B3d8d15D7', | ||
RelayHub: '0x145845fd06c85B7EA1AA2d030E1a747B3d8d15D7', | ||
SmartWallet: '0x145845fd06c85B7EA1AA2d030E1a747B3d8d15D7', | ||
SmartWalletFactory: '0x145845fd06c85B7EA1AA2d030E1a747B3d8d15D7', | ||
SmartWalletDeployVerifier: '0x145845fd06c85B7EA1AA2d030E1a747B3d8d15D7', | ||
SmartWalletRelayVerifier: '0x145845fd06c85B7EA1AA2d030E1a747B3d8d15D7', | ||
CustomSmartWallet: '0x145845fd06c85B7EA1AA2d030E1a747B3d8d15D7', | ||
CustomSmartWalletFactory: '0x145845fd06c85B7EA1AA2d030E1a747B3d8d15D7', | ||
CustomSmartWalletDeployVerifier: | ||
'0x145845fd06c85B7EA1AA2d030E1a747B3d8d15D7', | ||
CustomSmartWalletRelayVerifier: | ||
'0x145845fd06c85B7EA1AA2d030E1a747B3d8d15D7', | ||
UtilToken: '0x145845fd06c85B7EA1AA2d030E1a747B3d8d15D7', | ||
}; | ||
|
||
const chainContractAddresses = { | ||
'33': contractAddresses, | ||
}; | ||
|
||
let spyWriteFileSync: sinon.SinonSpy; | ||
|
||
beforeEach(function () { | ||
spyWriteFileSync = sinon.spy(fs, 'writeFileSync'); | ||
hardhat.hardhatArguments.network = 'regtest'; | ||
hardhat.config.networks.regtest.chainId = 33; | ||
}); | ||
|
||
afterEach(function () { | ||
sinon.restore(); | ||
}); | ||
|
||
it('should generate a json config file with existing config file', function () { | ||
sinon.stub(fs, 'existsSync').returns(true); | ||
sinon | ||
.stub(fs, 'readFileSync') | ||
.returns(JSON.stringify(chainContractAddresses)); | ||
generateJsonConfig(contractAddresses); | ||
spyWriteFileSync.calledOnceWith('contract-addresses.json', JSON.stringify(chainContractAddresses)); | ||
}); | ||
|
||
it('should generate a json config file when config file is not present', function () { | ||
sinon.stub(fs, 'existsSync').returns(false); | ||
generateJsonConfig(contractAddresses); | ||
spyWriteFileSync.calledOnceWith('contract-addresses.json', JSON.stringify(chainContractAddresses)); | ||
}); | ||
|
||
it('should throw if network is undefined', function () { | ||
sinon.stub(fs, 'existsSync').returns(true); | ||
sinon | ||
.stub(fs, 'readFileSync') | ||
.returns(JSON.stringify(chainContractAddresses)); | ||
hardhat.hardhatArguments.network = undefined; | ||
hardhat.config.networks.regtest.chainId = 33; | ||
expect(() => generateJsonConfig(contractAddresses)).to.throw('Unknown Network'); | ||
}); | ||
|
||
it('should throw if chainId is undefined', function () { | ||
sinon.stub(fs, 'existsSync').returns(true); | ||
sinon | ||
.stub(fs, 'readFileSync') | ||
.returns(JSON.stringify(chainContractAddresses)); | ||
hardhat.hardhatArguments.network = 'regtest'; | ||
hardhat.config.networks.regtest.chainId = undefined; | ||
expect(() => generateJsonConfig(contractAddresses)).to.throw('Unknown Chain Id'); | ||
}); | ||
}); | ||
}); |