Skip to content

Commit

Permalink
Merge pull request #726 from NexusMutual/fix/test-for-nxmaster-proxy-…
Browse files Browse the repository at this point in the history
…creation

Test & Fix: NXMaster proxy creation with predictable address + fix for event emission
  • Loading branch information
roxdanila committed Feb 14, 2023
2 parents 21203bc + 80d9417 commit 32a5ba5
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 1 deletion.
2 changes: 1 addition & 1 deletion contracts/modules/governance/NXMaster.sol
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ contract NXMaster is INXMMaster {
up.changeMasterAddress(address(this));
up.changeDependentContractAddress();

emit InternalContractAdded(contractCode, contractAddress, ContractType(_type));
emit InternalContractAdded(contractCode, contractAddress, ContractType(contractType));
}

/// @dev upgrades multiple contracts at a time
Expand Down
44 changes: 44 additions & 0 deletions test/integration/Master/master.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ const { submitProposal } = require('../utils').governance;
const { hex } = require('../utils').helpers;
const { parseEther, defaultAbiCoder } = ethers.utils;
const { AddressZero } = ethers.constants;
const { BigNumber } = ethers;

const MAX_ADDRESS = '0xffffffffffffffffffffffffffffffffffffffff';

async function assertNewAddresses(master, contractCodes, newAddresses, contractType) {
for (let i = 0; i < contractCodes.length; i++) {
Expand All @@ -26,6 +29,12 @@ async function assertNewAddresses(master, contractCodes, newAddresses, contractT
}
}

const encoder = (types, values) => {
const abiCoder = ethers.utils.defaultAbiCoder;
const encodedParams = abiCoder.encode(types, values);
return encodedParams.slice(2);
};

describe('master', function () {
it('adds new replaceable contract which can execute internal functions', async function () {
const { master, gv } = this.contracts;
Expand Down Expand Up @@ -72,6 +81,41 @@ describe('master', function () {
await newContractInstance.mint(this.accounts.defaultSender.address, parseEther('1'));
});

it('adds new proxy contract with a predictable address', async function () {
const { master, gv } = this.contracts;

const MMockNewContract = await ethers.getContractFactory('MMockNewContract');
const newContract = await MMockNewContract.deploy();

const salt = 2;

const contractTypeAndSalt = BigNumber.from(2).shl(8).add(ContractTypes.Proxy);

const code = hex('XX');
const actionData = defaultAbiCoder.encode(
['bytes2[]', 'address[]', 'uint[]'],
[[code], [newContract.address], [contractTypeAndSalt]],
);
await submitProposal(gv, ProposalCategory.newContracts, actionData, [this.accounts.defaultSender]);

const address = await master.getLatestAddress(code);
const proxy = await ethers.getContractAt('OwnedUpgradeabilityProxy', address);

const implementation = await proxy.implementation();
assert.equal(implementation, newContract.address);

const OwnedUpgradeabilityProxy = await ethers.getContractFactory('OwnedUpgradeabilityProxy');

const saltHex = Buffer.from(salt.toString(16).padStart(64, '0'), 'hex');

const initCode = OwnedUpgradeabilityProxy.bytecode + encoder(['address'], [MAX_ADDRESS]);
const initCodeHash = ethers.utils.keccak256(initCode);

const expectedProxyAddress = ethers.utils.getCreate2Address(master.address, saltHex, initCodeHash);

expect(proxy.address).to.be.equal(expectedProxyAddress);
});

it('replace contract', async function () {
const { master, gv } = this.contracts;
const owner = this.accounts.defaultSender;
Expand Down

0 comments on commit 32a5ba5

Please sign in to comment.