-
Notifications
You must be signed in to change notification settings - Fork 18
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 #50 from sygmaprotocol/nmlinaric/colors-example
Add colors example for using generic handler v1
- Loading branch information
Showing
8 changed files
with
335 additions
and
7 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
// SPDX-License-Identifier: UNLICENSED | ||
pragma solidity 0.8.11; | ||
|
||
contract Colors { | ||
bytes32[] public colorsArray; | ||
|
||
uint256 public colorCounter = 0; | ||
|
||
event setColorEvent(bytes32 color); | ||
event metadataDepositorEvent(address depositorAddress); | ||
|
||
function setColorOnDeploy(bytes32 color) public { | ||
colorsArray.push(color); | ||
} | ||
|
||
function setColor(bytes32 metadataDepositor, bytes32 color) public { | ||
colorsArray.push(color); | ||
colorCounter++; | ||
|
||
address depositorAddress = address(uint160(uint256(metadataDepositor))); | ||
|
||
emit setColorEvent(color); | ||
emit metadataDepositorEvent(depositorAddress); | ||
} | ||
|
||
function popColor() public { | ||
colorsArray.pop(); | ||
} | ||
|
||
function getColorsArrayLenght() public view returns (uint256 l) { | ||
return colorsArray.length; | ||
} | ||
|
||
function getCurrentColors(uint256 index) | ||
public | ||
view | ||
returns (bytes32 colorReturned) | ||
{ | ||
colorReturned = colorsArray[index]; | ||
return colorReturned; | ||
} | ||
|
||
function insertColorToColorsArray(bytes32 newColor) public { | ||
colorsArray.push(newColor); | ||
emit setColorEvent(newColor); | ||
} | ||
|
||
function findColor(bytes32 color) | ||
public | ||
view | ||
returns (bytes32 colorFound) | ||
{ | ||
for (uint i = 0; i < colorsArray.length; i++) { | ||
bytes32 c = colorsArray[i]; | ||
|
||
if ( | ||
keccak256(abi.encodePacked((color))) == | ||
keccak256(abi.encodePacked((c))) | ||
) { | ||
colorFound = c; | ||
break; | ||
} | ||
} | ||
return colorFound; | ||
} | ||
} |
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,14 @@ | ||
/** | ||
* Copyright 2020 ChainSafe Systems | ||
* SPDX-License-Identifier: LGPL-3.0-only | ||
*/ | ||
|
||
const ColorsContract = artifacts.require("Colors"); | ||
|
||
module.exports = async function(deployer, network) { | ||
// deploy colors example contract | ||
await deployer.deploy(ColorsContract); | ||
const colorsInstance = await ColorsContract.deployed(); | ||
|
||
console.log("Colors contract address:", "\t", colorsInstance.address); | ||
} |
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,126 @@ | ||
/** | ||
* Copyright 2020 ChainSafe Systems | ||
* SPDX-License-Identifier: LGPL-3.0-only | ||
*/ | ||
|
||
const TruffleAssert = require('truffle-assertions'); | ||
const Ethers = require('ethers'); | ||
const Helpers = require('../../../helpers'); | ||
|
||
const ColorsContract = artifacts.require("Colors"); | ||
const GenericHandlerContract = artifacts.require("GenericHandlerV1"); | ||
const WithDepositorContract = artifacts.require("WithDepositor"); | ||
const ReturnDataContract = artifacts.require("ReturnData"); | ||
|
||
contract('GenericHandlerV1 colors example - [deposit]', async (accounts) => { | ||
const originDomainID = 1; | ||
const destinationDomainID = 2; | ||
const expectedDepositNonce = 1; | ||
|
||
const depositorAddress = accounts[1]; | ||
|
||
const feeData = '0x'; | ||
const destinationMaxFee = 2000000; | ||
const hexRedColor = Helpers.toHex("0xD2042D", 32); | ||
|
||
let BridgeInstance; | ||
let ColorsInstance; | ||
|
||
let resourceID; | ||
let depositFunctionSignature; | ||
let GenericHandlerInstance; | ||
let depositData; | ||
|
||
beforeEach(async () => { | ||
await Promise.all([ | ||
BridgeInstance = await Helpers.deployBridge(originDomainID, accounts[0]), | ||
ColorsContract.new().then(instance => ColorsInstance = instance), | ||
WithDepositorContract.new().then(instance => WithDepositorInstance = instance), | ||
ReturnDataContract.new().then(instance => ReturnDataInstance = instance), | ||
]); | ||
|
||
resourceID = Helpers.createResourceID(ColorsInstance.address, originDomainID) | ||
|
||
GenericHandlerInstance = await GenericHandlerContract.new( | ||
BridgeInstance.address); | ||
|
||
await BridgeInstance.adminSetGenericResource(GenericHandlerInstance.address, resourceID, ColorsInstance.address, Helpers.blankFunctionSig, Helpers.blankFunctionDepositorOffset, Helpers.blankFunctionSig); | ||
|
||
depositFunctionSignature = Helpers.getFunctionSignature(ColorsInstance, 'setColor'); | ||
|
||
|
||
depositData = Helpers.createGenericDepositDataV1( | ||
depositFunctionSignature, | ||
ColorsInstance.address, | ||
destinationMaxFee, | ||
depositorAddress, | ||
hexRedColor, | ||
false // don't append depositor for destination chain check | ||
); | ||
|
||
// set MPC address to unpause the Bridge | ||
await BridgeInstance.endKeygen(Helpers.mpcAddress); | ||
}); | ||
|
||
it('deposit can be made successfully', async () => { | ||
await TruffleAssert.passes(BridgeInstance.deposit( | ||
destinationDomainID, | ||
resourceID, | ||
depositData, | ||
feeData, | ||
{ from: depositorAddress } | ||
)); | ||
}); | ||
|
||
it('depositEvent is emitted with expected values', async () => { | ||
const depositTx = await BridgeInstance.deposit( | ||
destinationDomainID, | ||
resourceID, | ||
depositData, | ||
feeData, | ||
{ from: depositorAddress } | ||
); | ||
|
||
TruffleAssert.eventEmitted(depositTx, 'Deposit', (event) => { | ||
return event.destinationDomainID.toNumber() === destinationDomainID && | ||
event.resourceID === resourceID.toLowerCase() && | ||
event.depositNonce.toNumber() === expectedDepositNonce && | ||
event.user === depositorAddress && | ||
event.data === depositData && | ||
event.handlerResponse === null | ||
}); | ||
}); | ||
|
||
it('deposit data should be of required length', async () => { | ||
const invalidDepositData = "0x" + "02a3d".repeat(31); | ||
|
||
await TruffleAssert.reverts(BridgeInstance.deposit( | ||
destinationDomainID, | ||
resourceID, | ||
invalidDepositData, | ||
feeData, | ||
{ from: depositorAddress } | ||
), "Incorrect data length"); | ||
}); | ||
|
||
it('should revert if metadata encoded depositor does not match deposit depositor', async () => { | ||
const invalidDepositorAddress = accounts[2]; | ||
|
||
const invalidDepositData = Helpers.createGenericDepositDataV1( | ||
depositFunctionSignature, | ||
ColorsInstance.address, | ||
destinationMaxFee, | ||
invalidDepositorAddress, | ||
hexRedColor, | ||
false // don't append depositor for destination chain check | ||
); | ||
|
||
await TruffleAssert.reverts(BridgeInstance.deposit( | ||
destinationDomainID, | ||
resourceID, | ||
invalidDepositData, | ||
feeData, | ||
{ from: depositorAddress } | ||
), "incorrect depositor in deposit data"); | ||
}); | ||
}); |
117 changes: 117 additions & 0 deletions
117
test/handlers/generic/colors_example/executeProposal.js
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,117 @@ | ||
/** | ||
* Copyright 2020 ChainSafe Systems | ||
* SPDX-License-Identifier: LGPL-3.0-only | ||
*/ | ||
|
||
const TruffleAssert = require('truffle-assertions'); | ||
const Ethers = require('ethers'); | ||
const Helpers = require('../../../helpers'); | ||
|
||
const ColorsContract = artifacts.require("Colors"); | ||
const GenericHandlerContract = artifacts.require("GenericHandlerV1"); | ||
|
||
contract('GenericHandlerV1 colors example - [Execute Proposal]', async (accounts) => { | ||
const originDomainID = 1; | ||
const destinationDomainID = 2; | ||
const expectedDepositNonce = 1; | ||
|
||
const depositorAddress = accounts[1]; | ||
const relayer1Address = accounts[2]; | ||
const relayer2Address = accounts[3]; | ||
|
||
const feeData = '0x'; | ||
const destinationMaxFee = 2000000; | ||
const hexRedColor = Helpers.toHex("0xD2042D", 32); | ||
|
||
let BridgeInstance; | ||
let ColorsInstance; | ||
|
||
let resourceID; | ||
let depositFunctionSignature; | ||
let GenericHandlerInstance; | ||
let depositData; | ||
let proposal; | ||
|
||
beforeEach(async () => { | ||
await Promise.all([ | ||
BridgeInstance = await Helpers.deployBridge(destinationDomainID, accounts[0]), | ||
ColorsContract.new().then(instance => ColorsInstance = instance) | ||
]); | ||
|
||
resourceID = Helpers.createResourceID(ColorsInstance.address, originDomainID); | ||
|
||
GenericHandlerInstance = await GenericHandlerContract.new( | ||
BridgeInstance.address); | ||
|
||
await BridgeInstance.adminSetGenericResource(GenericHandlerInstance.address, resourceID, ColorsInstance.address, Helpers.blankFunctionSig, Helpers.blankFunctionDepositorOffset, Helpers.blankFunctionSig); | ||
|
||
depositFunctionSignature = Helpers.getFunctionSignature(ColorsInstance, 'setColor'); | ||
|
||
depositData = | ||
Helpers.createGenericDepositDataV1( | ||
depositFunctionSignature, | ||
ColorsInstance.address, | ||
destinationMaxFee, | ||
depositorAddress, | ||
hexRedColor, | ||
false // don't append depositor for destination chain check | ||
); | ||
|
||
proposal = { | ||
originDomainID: originDomainID, | ||
depositNonce: expectedDepositNonce, | ||
data: depositData, | ||
resourceID: resourceID | ||
}; | ||
|
||
// set MPC address to unpause the Bridge | ||
await BridgeInstance.endKeygen(Helpers.mpcAddress); | ||
}); | ||
|
||
it('deposit can be executed successfully', async () => { | ||
const proposalSignedData = await Helpers.signTypedProposal(BridgeInstance.address, [proposal]); | ||
await TruffleAssert.passes(BridgeInstance.deposit( | ||
originDomainID, | ||
resourceID, | ||
depositData, | ||
feeData, | ||
{ from: depositorAddress } | ||
)); | ||
|
||
// relayer1 executes the proposal | ||
await TruffleAssert.passes(BridgeInstance.executeProposal( | ||
proposal, | ||
proposalSignedData, | ||
{ from: relayer1Address } | ||
)); | ||
|
||
// Verifying color was stored in ColorsInstance contract | ||
const storedColor = await ColorsInstance.findColor(hexRedColor); | ||
assert.equal(storedColor, hexRedColor); | ||
}); | ||
|
||
it('setColor event should be emitted', async () => { | ||
const proposalSignedData = await Helpers.signTypedProposal(BridgeInstance.address, [proposal]); | ||
|
||
|
||
await TruffleAssert.passes(BridgeInstance.deposit( | ||
originDomainID, | ||
resourceID, | ||
depositData, | ||
feeData, | ||
{ from: depositorAddress } | ||
)); | ||
|
||
// relayer1 executes the proposal | ||
const executeTx = await BridgeInstance.executeProposal( | ||
proposal, | ||
proposalSignedData, | ||
{ from: relayer2Address } | ||
); | ||
|
||
const internalTx = await TruffleAssert.createTransactionResult(ColorsInstance, executeTx.tx); | ||
TruffleAssert.eventEmitted(internalTx, 'setColorEvent', event => { | ||
return event.color === hexRedColor; | ||
}); | ||
}); | ||
}); |
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