From 3b7d3ea867f7f55411b8d2079d3f9fb9362e8967 Mon Sep 17 00:00:00 2001 From: Alessandro Manfredi Date: Mon, 19 Feb 2024 13:15:14 +0100 Subject: [PATCH 01/12] feat(contracts): adds domain to settings --- .../evm/contracts/ownable/GiriGiriBashi.sol | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/packages/evm/contracts/ownable/GiriGiriBashi.sol b/packages/evm/contracts/ownable/GiriGiriBashi.sol index fd06d8ae..b9c320f0 100644 --- a/packages/evm/contracts/ownable/GiriGiriBashi.sol +++ b/packages/evm/contracts/ownable/GiriGiriBashi.sol @@ -10,7 +10,7 @@ contract GiriGiriBashi is IGiriGiriBashi, ShuSo { address payable public bondRecipient; // address that bonds from unsuccessful challenges should be sent to. mapping(uint256 => uint256) public heads; // highest Id reported. mapping(uint256 => uint256) public challengeRanges; // how far beyond the current highestId can a challenged. - mapping(IAdapter => Settings) public settings; + mapping(IAdapter => mapping(uint256 => Settings)) public settings; mapping(bytes32 => Challenge) public challenges; // current challenges. constructor(address _owner, address _hashi, address payable _bondRecipient) ShuSo(_owner, _hashi) { @@ -30,8 +30,8 @@ contract GiriGiriBashi is IGiriGiriBashi, ShuSo { /// @inheritdoc IGiriGiriBashi function challengeAdapter(uint256 domain, uint256 id, IAdapter adapter) public payable { if (adapters[domain][adapter].previous == IAdapter(address(0))) revert AdapterNotEnabled(adapter); - if (msg.value < settings[adapter].minimumBond) revert NotEnoughValue(adapter, msg.value); - if (settings[adapter].quarantined) revert AlreadyQuarantined(adapter); + if (msg.value < settings[adapter][domain].minimumBond) revert NotEnoughValue(adapter, msg.value); + if (settings[adapter][domain].quarantined) revert AlreadyQuarantined(adapter); bytes32 challengeId = getChallengeId(domain, id, adapter); if (challenges[challengeId].challenger != address(0)) @@ -41,10 +41,10 @@ contract GiriGiriBashi is IGiriGiriBashi, ShuSo { // check if id is less than highestId + challengeRange, revert if false // check if id is lower than highestId - idDepth, revert if true uint256 challengeRange = challengeRanges[domain]; - uint256 idDepth = settings[adapter].idDepth; + uint256 idDepth = settings[adapter][domain].idDepth; uint256 head = heads[domain]; if ( - id < settings[adapter].startId || // before start id + id < settings[adapter][domain].startId || // before start id (challengeRange != 0 && id >= head && id - head > challengeRange) || // over domain challenge range (idDepth != 0 && head > idDepth && id <= head - idDepth) // outside of adapter idDepth ) revert OutOfRange(adapter, id); @@ -129,7 +129,7 @@ contract GiriGiriBashi is IGiriGiriBashi, ShuSo { if (currentAdapters.length != newAdapters.length || currentAdapters.length != _settings.length) revert UnequalArrayLengths(); for (uint i = 0; i < currentAdapters.length; i++) { - if (!settings[currentAdapters[i]].quarantined) revert AdapterNotQuarantined(currentAdapters[i]); + if (!settings[currentAdapters[i]][domain].quarantined) revert AdapterNotQuarantined(currentAdapters[i]); } _disableAdapters(domain, currentAdapters); _enableAdapters(domain, newAdapters); @@ -149,7 +149,7 @@ contract GiriGiriBashi is IGiriGiriBashi, ShuSo { revert ChallengeNotFound(challengeId, domain, id, adapter); Challenge storage challenge = challenges[challengeId]; - Settings storage adapterSettings = settings[adapter]; + Settings storage adapterSettings = settings[adapter][domain]; bytes32 storedHash = adapter.getHash(domain, id); if (storedHash == bytes32(0)) { @@ -219,11 +219,11 @@ contract GiriGiriBashi is IGiriGiriBashi, ShuSo { if (_adapters.length != _settings.length) revert UnequalArrayLengths(); for (uint i = 0; i < _adapters.length; i++) { IAdapter adapter = _adapters[i]; - settings[adapter].quarantined = false; - settings[adapter].minimumBond = _settings[i].minimumBond; - settings[adapter].startId = _settings[i].startId; - settings[adapter].idDepth = _settings[i].idDepth; - settings[adapter].timeout = _settings[i].timeout; + settings[adapter][domain].quarantined = false; + settings[adapter][domain].minimumBond = _settings[i].minimumBond; + settings[adapter][domain].startId = _settings[i].startId; + settings[adapter][domain].idDepth = _settings[i].idDepth; + settings[adapter][domain].timeout = _settings[i].timeout; emit SettingsInitialized(domain, adapter, _settings[i]); } } From aafcd2ec9aa22242a4ba46ad8e6d294d03a9e7bd Mon Sep 17 00:00:00 2001 From: Alessandro Manfredi Date: Mon, 19 Feb 2024 13:22:53 +0100 Subject: [PATCH 02/12] refactor(contracts): rn uint into uint256 --- packages/evm/contracts/ownable/GiriGiriBashi.sol | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/evm/contracts/ownable/GiriGiriBashi.sol b/packages/evm/contracts/ownable/GiriGiriBashi.sol index b9c320f0..3005c64f 100644 --- a/packages/evm/contracts/ownable/GiriGiriBashi.sol +++ b/packages/evm/contracts/ownable/GiriGiriBashi.sol @@ -77,11 +77,11 @@ contract GiriGiriBashi is IGiriGiriBashi, ShuSo { if (confidence >= threshold) revert CannotProveNoConfidence(domain, id, _adapters); bytes32[] memory hashes = new bytes32[](_adapters.length); - for (uint i = 0; i < _adapters.length; i++) hashes[i] = _adapters[i].getHash(domain, id); + for (uint256 i = 0; i < _adapters.length; i++) hashes[i] = _adapters[i].getHash(domain, id); // prove that each member of _adapters disagrees - for (uint i = 0; i < hashes.length; i++) - for (uint j = 0; j < hashes.length; j++) + for (uint256 i = 0; i < hashes.length; i++) + for (uint256 j = 0; j < hashes.length; j++) if (hashes[i] == hashes[j] && i != j) revert AdaptersAgreed(_adapters[i], _adapters[j]); domains[domain].threshold = type(uint256).max; @@ -128,7 +128,7 @@ contract GiriGiriBashi is IGiriGiriBashi, ShuSo { ) public onlyOwner { if (currentAdapters.length != newAdapters.length || currentAdapters.length != _settings.length) revert UnequalArrayLengths(); - for (uint i = 0; i < currentAdapters.length; i++) { + for (uint256 i = 0; i < currentAdapters.length; i++) { if (!settings[currentAdapters[i]][domain].quarantined) revert AdapterNotQuarantined(currentAdapters[i]); } _disableAdapters(domain, currentAdapters); @@ -217,7 +217,7 @@ contract GiriGiriBashi is IGiriGiriBashi, ShuSo { function initSettings(uint256 domain, IAdapter[] memory _adapters, Settings[] memory _settings) private { if (_adapters.length != _settings.length) revert UnequalArrayLengths(); - for (uint i = 0; i < _adapters.length; i++) { + for (uint256 i = 0; i < _adapters.length; i++) { IAdapter adapter = _adapters[i]; settings[adapter][domain].quarantined = false; settings[adapter][domain].minimumBond = _settings[i].minimumBond; From 3557312f7b37b257d49991823506b6eda932f3ac Mon Sep 17 00:00:00 2001 From: Alessandro Manfredi Date: Mon, 19 Feb 2024 13:46:25 +0100 Subject: [PATCH 03/12] refactor(contracts): changes settings mapping --- .../evm/contracts/ownable/GiriGiriBashi.sol | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/packages/evm/contracts/ownable/GiriGiriBashi.sol b/packages/evm/contracts/ownable/GiriGiriBashi.sol index 3005c64f..f820e998 100644 --- a/packages/evm/contracts/ownable/GiriGiriBashi.sol +++ b/packages/evm/contracts/ownable/GiriGiriBashi.sol @@ -10,7 +10,7 @@ contract GiriGiriBashi is IGiriGiriBashi, ShuSo { address payable public bondRecipient; // address that bonds from unsuccessful challenges should be sent to. mapping(uint256 => uint256) public heads; // highest Id reported. mapping(uint256 => uint256) public challengeRanges; // how far beyond the current highestId can a challenged. - mapping(IAdapter => mapping(uint256 => Settings)) public settings; + mapping(uint256 => mapping(IAdapter => Settings)) public settings; mapping(bytes32 => Challenge) public challenges; // current challenges. constructor(address _owner, address _hashi, address payable _bondRecipient) ShuSo(_owner, _hashi) { @@ -30,8 +30,8 @@ contract GiriGiriBashi is IGiriGiriBashi, ShuSo { /// @inheritdoc IGiriGiriBashi function challengeAdapter(uint256 domain, uint256 id, IAdapter adapter) public payable { if (adapters[domain][adapter].previous == IAdapter(address(0))) revert AdapterNotEnabled(adapter); - if (msg.value < settings[adapter][domain].minimumBond) revert NotEnoughValue(adapter, msg.value); - if (settings[adapter][domain].quarantined) revert AlreadyQuarantined(adapter); + if (msg.value < settings[domain][adapter].minimumBond) revert NotEnoughValue(adapter, msg.value); + if (settings[domain][adapter].quarantined) revert AlreadyQuarantined(adapter); bytes32 challengeId = getChallengeId(domain, id, adapter); if (challenges[challengeId].challenger != address(0)) @@ -41,10 +41,10 @@ contract GiriGiriBashi is IGiriGiriBashi, ShuSo { // check if id is less than highestId + challengeRange, revert if false // check if id is lower than highestId - idDepth, revert if true uint256 challengeRange = challengeRanges[domain]; - uint256 idDepth = settings[adapter][domain].idDepth; + uint256 idDepth = settings[domain][adapter].idDepth; uint256 head = heads[domain]; if ( - id < settings[adapter][domain].startId || // before start id + id < settings[domain][adapter].startId || // before start id (challengeRange != 0 && id >= head && id - head > challengeRange) || // over domain challenge range (idDepth != 0 && head > idDepth && id <= head - idDepth) // outside of adapter idDepth ) revert OutOfRange(adapter, id); @@ -129,7 +129,7 @@ contract GiriGiriBashi is IGiriGiriBashi, ShuSo { if (currentAdapters.length != newAdapters.length || currentAdapters.length != _settings.length) revert UnequalArrayLengths(); for (uint256 i = 0; i < currentAdapters.length; i++) { - if (!settings[currentAdapters[i]][domain].quarantined) revert AdapterNotQuarantined(currentAdapters[i]); + if (!settings[domain][currentAdapters[i]].quarantined) revert AdapterNotQuarantined(currentAdapters[i]); } _disableAdapters(domain, currentAdapters); _enableAdapters(domain, newAdapters); @@ -149,7 +149,7 @@ contract GiriGiriBashi is IGiriGiriBashi, ShuSo { revert ChallengeNotFound(challengeId, domain, id, adapter); Challenge storage challenge = challenges[challengeId]; - Settings storage adapterSettings = settings[adapter][domain]; + Settings storage adapterSettings = settings[domain][adapter]; bytes32 storedHash = adapter.getHash(domain, id); if (storedHash == bytes32(0)) { @@ -219,11 +219,11 @@ contract GiriGiriBashi is IGiriGiriBashi, ShuSo { if (_adapters.length != _settings.length) revert UnequalArrayLengths(); for (uint256 i = 0; i < _adapters.length; i++) { IAdapter adapter = _adapters[i]; - settings[adapter][domain].quarantined = false; - settings[adapter][domain].minimumBond = _settings[i].minimumBond; - settings[adapter][domain].startId = _settings[i].startId; - settings[adapter][domain].idDepth = _settings[i].idDepth; - settings[adapter][domain].timeout = _settings[i].timeout; + settings[domain][adapter].quarantined = false; + settings[domain][adapter].minimumBond = _settings[i].minimumBond; + settings[domain][adapter].startId = _settings[i].startId; + settings[domain][adapter].idDepth = _settings[i].idDepth; + settings[domain][adapter].timeout = _settings[i].timeout; emit SettingsInitialized(domain, adapter, _settings[i]); } } From 5d1d3c03802c0e3165f33175f8746466cb8f4600 Mon Sep 17 00:00:00 2001 From: Alessandro Manfredi Date: Mon, 19 Feb 2024 14:48:11 +0100 Subject: [PATCH 04/12] fix(contracts): adds a check to prevent using the same adapters + order to resolveChallenge --- .../evm/contracts/interfaces/IGiriGiriBashi.sol | 1 + packages/evm/contracts/ownable/GiriGiriBashi.sol | 15 +++++++++------ 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/packages/evm/contracts/interfaces/IGiriGiriBashi.sol b/packages/evm/contracts/interfaces/IGiriGiriBashi.sol index 2b917028..2f2859c9 100644 --- a/packages/evm/contracts/interfaces/IGiriGiriBashi.sol +++ b/packages/evm/contracts/interfaces/IGiriGiriBashi.sol @@ -32,6 +32,7 @@ interface IGiriGiriBashi is IShuSho { error ChallengeRangeAlreadySet(uint256 domain); error CountMustBeZero(uint256 domain); error DuplicateChallenge(bytes32 challengeId, uint256 domain, uint256 id, IAdapter adapter); + error InvalidAdapters(IAdapter[] adapters, IAdapter adapter); error NoConfidenceRequired(); error NotEnoughValue(IAdapter adapter, uint256 value); error OutOfRange(IAdapter adapter, uint256 id); diff --git a/packages/evm/contracts/ownable/GiriGiriBashi.sol b/packages/evm/contracts/ownable/GiriGiriBashi.sol index f820e998..3a4f76e4 100644 --- a/packages/evm/contracts/ownable/GiriGiriBashi.sol +++ b/packages/evm/contracts/ownable/GiriGiriBashi.sol @@ -148,24 +148,29 @@ contract GiriGiriBashi is IGiriGiriBashi, ShuSo { if (challenges[challengeId].challenger == address(0)) revert ChallengeNotFound(challengeId, domain, id, adapter); + for (uint256 i = 0; i < _adapters.length; ) { + if (_adapters[i] == adapter) revert InvalidAdapters(_adapters, adapter); + unchecked { + ++i; + } + } + Challenge storage challenge = challenges[challengeId]; Settings storage adapterSettings = settings[domain][adapter]; bytes32 storedHash = adapter.getHash(domain, id); if (storedHash == bytes32(0)) { - // check block.timestamp is greater than challenge.timestamp + adapterSettings.timeout, revert if false. if (block.timestamp < challenge.timestamp + adapterSettings.timeout) revert AdapterHasNotYetTimedOut(adapter); adapterSettings.quarantined = true; - // send bond to challenger challenge.challenger.transfer(challenge.bond); success = true; } else { // if _adapters + 1 equals threshold && _adapters + adapter report the same header - if (_adapters.length + 1 == domains[domain].threshold) { + if (_adapters.length == domains[domain].threshold - 1) { + checkAdapterOrderAndValidity(domain, _adapters); bytes32 canonicalHash = hashi.getHash(domain, id, _adapters); if (canonicalHash == storedHash) { - // return bond to recipient bondRecipient.transfer(challenge.bond); success = false; } else { @@ -178,9 +183,7 @@ contract GiriGiriBashi is IGiriGiriBashi, ShuSo { bondRecipient.transfer(challenge.bond); success = false; } else { - // quaratine adapter adapterSettings.quarantined = true; - // return bond to challenger challenge.challenger.transfer(challenge.bond); success = true; } From 35c53d925b084c6d7bd5b020685e852d526a34d0 Mon Sep 17 00:00:00 2001 From: Alessandro Manfredi Date: Mon, 19 Feb 2024 15:38:11 +0100 Subject: [PATCH 05/12] refactor(evm): rn InvalidAdapters into AdaptersCannotContainChallengedAdapter --- packages/evm/contracts/interfaces/IGiriGiriBashi.sol | 2 +- packages/evm/contracts/ownable/GiriGiriBashi.sol | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/evm/contracts/interfaces/IGiriGiriBashi.sol b/packages/evm/contracts/interfaces/IGiriGiriBashi.sol index 2f2859c9..32d60d2a 100644 --- a/packages/evm/contracts/interfaces/IGiriGiriBashi.sol +++ b/packages/evm/contracts/interfaces/IGiriGiriBashi.sol @@ -23,6 +23,7 @@ interface IGiriGiriBashi is IShuSho { uint256 timeout; // grace period in which the adapter must report on an in-range id after being challenged. } + error AdaptersCannotContainChallengedAdapter(IAdapter[] adapters, IAdapter adapter); error AdapterHasNotYetTimedOut(IAdapter adapter); error AdapterNotQuarantined(IAdapter adapter); error AdaptersAgreed(IAdapter adapter1, IAdapter adapter2); @@ -32,7 +33,6 @@ interface IGiriGiriBashi is IShuSho { error ChallengeRangeAlreadySet(uint256 domain); error CountMustBeZero(uint256 domain); error DuplicateChallenge(bytes32 challengeId, uint256 domain, uint256 id, IAdapter adapter); - error InvalidAdapters(IAdapter[] adapters, IAdapter adapter); error NoConfidenceRequired(); error NotEnoughValue(IAdapter adapter, uint256 value); error OutOfRange(IAdapter adapter, uint256 id); diff --git a/packages/evm/contracts/ownable/GiriGiriBashi.sol b/packages/evm/contracts/ownable/GiriGiriBashi.sol index 3a4f76e4..fb3aac56 100644 --- a/packages/evm/contracts/ownable/GiriGiriBashi.sol +++ b/packages/evm/contracts/ownable/GiriGiriBashi.sol @@ -149,7 +149,7 @@ contract GiriGiriBashi is IGiriGiriBashi, ShuSo { revert ChallengeNotFound(challengeId, domain, id, adapter); for (uint256 i = 0; i < _adapters.length; ) { - if (_adapters[i] == adapter) revert InvalidAdapters(_adapters, adapter); + if (_adapters[i] == adapter) revert AdaptersCannotContainChallengedAdapter(_adapters, adapter); unchecked { ++i; } From 872589d8494ba69aceb4668853358b20d7d66d47 Mon Sep 17 00:00:00 2001 From: Alessandro Manfredi Date: Tue, 20 Feb 2024 07:28:37 +0100 Subject: [PATCH 06/12] feat(test): adds GiriGiriBashi tests --- packages/evm/test/03_GiriGiriBashi.spec.ts | 62 +++++++++++++++++++--- 1 file changed, 54 insertions(+), 8 deletions(-) diff --git a/packages/evm/test/03_GiriGiriBashi.spec.ts b/packages/evm/test/03_GiriGiriBashi.spec.ts index 5b58c055..8fc61060 100644 --- a/packages/evm/test/03_GiriGiriBashi.spec.ts +++ b/packages/evm/test/03_GiriGiriBashi.spec.ts @@ -163,13 +163,13 @@ describe("GiriGiriBashi", function () { expect((await giriGiriBashi.adapters(DOMAIN_ID, ADDRESS_TWO)).previous).to.equal(LIST_END) expect((await giriGiriBashi.adapters(DOMAIN_ID, ADDRESS_THREE)).next).to.equal(LIST_END) expect((await giriGiriBashi.adapters(DOMAIN_ID, ADDRESS_THREE)).previous).to.equal(ADDRESS_TWO) - let adapterSettings = await giriGiriBashi.settings(ADDRESS_TWO) + let adapterSettings = await giriGiriBashi.settings(DOMAIN_ID, ADDRESS_TWO) expect(adapterSettings.quarantined).to.deep.equal(settings.quarantined) expect(adapterSettings.minimumBond).to.deep.equal(settings.minimumBond) expect(adapterSettings.startId).to.deep.equal(settings.startId) expect(adapterSettings.idDepth).to.deep.equal(settings.idDepth) expect(adapterSettings.timeout).to.deep.equal(settings.timeout) - adapterSettings = await giriGiriBashi.settings(ADDRESS_THREE) + adapterSettings = await giriGiriBashi.settings(DOMAIN_ID, ADDRESS_THREE) expect(adapterSettings.quarantined).to.deep.equal(settings.quarantined) expect(adapterSettings.minimumBond).to.deep.equal(settings.minimumBond) expect(adapterSettings.startId).to.deep.equal(settings.startId) @@ -300,6 +300,49 @@ describe("GiriGiriBashi", function () { .to.be.revertedWithCustomError(giriGiriBashi, "AlreadyQuarantined") .withArgs(mockAdapter.address) }) + it("Reverts if adapters array contains duplicates", async function () { + const { giriGiriBashi, mockAdapter, secondMockAdapter, settings } = await setup() + const adapters = [mockAdapter.address, secondMockAdapter.address].sort(compareAddresses) + await giriGiriBashi.enableAdapters(DOMAIN_ID, adapters, [settings, settings]) + + await giriGiriBashi.getHash(DOMAIN_ID, 21, adapters) + const head = await giriGiriBashi.heads(DOMAIN_ID) + const challengeBlock = head - CHALLENGE_RANGE + 2 + await giriGiriBashi.challengeAdapter(DOMAIN_ID, challengeBlock, mockAdapter.address, { + value: BOND, + }) + const challengeId = await giriGiriBashi.getChallengeId(DOMAIN_ID, challengeBlock, mockAdapter.address) + const challenge = await giriGiriBashi.challenges(challengeId) + const increaseAmount = challenge.timestamp.add(settings.timeout).add(1) + + await network.provider.send("evm_setNextBlockTimestamp", [increaseAmount.toHexString()]) + await mockAdapter.setHashes(DOMAIN_ID, [challengeBlock], [HASH_GOOD]) + await secondMockAdapter.setHashes(DOMAIN_ID, [challengeBlock], [HASH_GOOD]) + + await expect( + giriGiriBashi.resolveChallenge(DOMAIN_ID, challengeBlock, mockAdapter.address, [ + secondMockAdapter.address, + secondMockAdapter.address, + ]), + ).to.be.revertedWithCustomError(giriGiriBashi, "DuplicateOrOutOfOrderAdapters") + }) + it("Reverts if adapters array contains the challenged adapter", async function () { + const { giriGiriBashi, mockAdapter, secondMockAdapter, settings } = await setup() + const adapters = [mockAdapter.address, secondMockAdapter.address].sort(compareAddresses) + await giriGiriBashi.enableAdapters(DOMAIN_ID, adapters, [settings, settings]) + + await giriGiriBashi.getHash(DOMAIN_ID, 21, adapters) + const head = await giriGiriBashi.heads(DOMAIN_ID) + const challengeBlock = head - CHALLENGE_RANGE + 2 + await giriGiriBashi.challengeAdapter(DOMAIN_ID, challengeBlock, mockAdapter.address, { + value: BOND, + }) + + const wrongAdapters = [secondMockAdapter.address, mockAdapter.address] + await expect(giriGiriBashi.resolveChallenge(DOMAIN_ID, challengeBlock, mockAdapter.address, wrongAdapters)) + .to.revertedWithCustomError(giriGiriBashi, "AdaptersCannotContainChallengedAdapter") + .withArgs(wrongAdapters, mockAdapter.address) + }) it("Reverts if duplicate challenge exists", async function () { const { giriGiriBashi, mockAdapter, secondMockAdapter, settings } = await setup() const adapters = [mockAdapter.address, secondMockAdapter.address].sort(compareAddresses) @@ -436,7 +479,7 @@ describe("GiriGiriBashi", function () { const newBalance = await ethers.provider.getBalance(wallet.address) await expect(newBalance).to.be.greaterThan(previousBalance) - const quarantined = (await giriGiriBashi.settings(mockAdapter.address)).quarantined + const quarantined = (await giriGiriBashi.settings(DOMAIN_ID, mockAdapter.address)).quarantined await expect(quarantined).to.equal(true) }) it("Keeps bond if _adapters + adapter equals threshold and agree", async function () { @@ -451,10 +494,13 @@ describe("GiriGiriBashi", function () { value: BOND, }) + await mockAdapter.setHashes(DOMAIN_ID, [challengeBlock], [HASH_GOOD]) + await secondMockAdapter.setHashes(DOMAIN_ID, [challengeBlock], [HASH_GOOD]) + const balanceBefore = await ethers.provider.getBalance(ADDRESS_TWO) await giriGiriBashi.resolveChallenge(DOMAIN_ID, challengeBlock, mockAdapter.address, [secondMockAdapter.address]) expect(await ethers.provider.getBalance(ADDRESS_TWO)).to.equal(balanceBefore.add(BOND)) - const quarantined = (await giriGiriBashi.settings(mockAdapter.address)).quarantined + const quarantined = (await giriGiriBashi.settings(DOMAIN_ID, mockAdapter.address)).quarantined expect(quarantined).to.equal(false) }) it("Reverts if _adapters + adapter equals threshold and disagree", async function () { @@ -497,7 +543,7 @@ describe("GiriGiriBashi", function () { [secondMockAdapter.address, thirdMockAdapter.address].sort(compareAddresses), ) expect(await ethers.provider.getBalance(ADDRESS_TWO)).to.equal(previousBalance.add(BOND)) - const quarantined = (await giriGiriBashi.settings(mockAdapter.address)).quarantined + const quarantined = (await giriGiriBashi.settings(DOMAIN_ID, mockAdapter.address)).quarantined expect(quarantined).to.equal(false) }) it("Quarantines adapter and returns bond if challenged adapter disagrees with canonical hash", async function () { @@ -519,7 +565,7 @@ describe("GiriGiriBashi", function () { mockAdapter.address, [secondMockAdapter.address, thirdMockAdapter.address].sort(compareAddresses), ) - const quarantined = (await giriGiriBashi.settings(mockAdapter.address)).quarantined + const quarantined = (await giriGiriBashi.settings(DOMAIN_ID, mockAdapter.address)).quarantined await expect(quarantined).to.equal(true) }) it("Clears state after challenge is resolved", async function () { @@ -541,7 +587,7 @@ describe("GiriGiriBashi", function () { mockAdapter.address, [secondMockAdapter.address, thirdMockAdapter.address].sort(compareAddresses), ) - const quarantined = (await giriGiriBashi.settings(mockAdapter.address)).quarantined + const quarantined = (await giriGiriBashi.settings(DOMAIN_ID, mockAdapter.address)).quarantined expect(quarantined).to.equal(true) const challengeId = await giriGiriBashi.getChallengeId(DOMAIN_ID, challengeBlock, mockAdapter.address) const challenge = await giriGiriBashi.challenges(challengeId) @@ -717,7 +763,7 @@ describe("GiriGiriBashi", function () { expect( await giriGiriBashi.replaceQuarantinedAdapters(DOMAIN_ID, [mockAdapter.address], [ADDRESS_TWO], [settings]), ) - const adapterSettings = await giriGiriBashi.settings(ADDRESS_TWO) + const adapterSettings = await giriGiriBashi.settings(DOMAIN_ID, ADDRESS_TWO) expect(adapterSettings.quarantined).to.deep.equal(settings.quarantined) expect(adapterSettings.minimumBond).to.deep.equal(settings.minimumBond) expect(adapterSettings.startId).to.deep.equal(settings.startId) From 8c9b8af70edcb0cfcaeb8d57cd6514a3026cd8c5 Mon Sep 17 00:00:00 2001 From: Alessandro Manfredi Date: Tue, 20 Feb 2024 14:20:44 +0100 Subject: [PATCH 07/12] feat(contracts): adds notice comment to _setThreshold within ShuSho --- packages/evm/contracts/ownable/ShuSo.sol | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/evm/contracts/ownable/ShuSo.sol b/packages/evm/contracts/ownable/ShuSo.sol index ffdadc9d..5c03fecf 100644 --- a/packages/evm/contracts/ownable/ShuSo.sol +++ b/packages/evm/contracts/ownable/ShuSo.sol @@ -202,6 +202,9 @@ abstract contract ShuSo is IShuSho, OwnableUpgradeable { * @param threshold - Uint256 threshold to set for the given domain. * @notice Only callable by the owner of this contract. * @notice Reverts if threshold is already set to the given value. + * @notice It's IMPORTANT to set the threshold greater than or equal to _adapters.length + 1. + * Setting it lower would mean that the return value of _getThresholdHash + * would depend on the order of the adapters. */ function _setThreshold(uint256 domain, uint256 threshold) internal onlyOwner { if (domains[domain].threshold == threshold) revert DuplicateThreashold(threshold); From df77641fa58e9549c36eadcbbb33a7ca1d20af0c Mon Sep 17 00:00:00 2001 From: Alessandro Manfredi Date: Tue, 20 Feb 2024 15:49:11 +0100 Subject: [PATCH 08/12] fix(contracts & test): adds check to prevent settings the threhold less than the majority of the adapters within ShuSho --- packages/evm/contracts/interfaces/IShuSho.sol | 2 + .../evm/contracts/ownable/GiriGiriBashi.sol | 2 +- packages/evm/contracts/ownable/ShuSo.sol | 6 +- packages/evm/test/02_ShoyuBashi.spec.ts | 18 ++-- packages/evm/test/03_GiriGiriBashi.spec.ts | 82 +++++++++++++++---- 5 files changed, 85 insertions(+), 25 deletions(-) diff --git a/packages/evm/contracts/interfaces/IShuSho.sol b/packages/evm/contracts/interfaces/IShuSho.sol index 97feeecf..c573ab43 100644 --- a/packages/evm/contracts/interfaces/IShuSho.sol +++ b/packages/evm/contracts/interfaces/IShuSho.sol @@ -20,10 +20,12 @@ interface IShuSho { error AdapterNotEnabled(IAdapter adapter); error AdapterAlreadyEnabled(IAdapter adapter); + error CountCannotBeZero(); error DuplicateHashiAddress(IHashi hashi); error DuplicateOrOutOfOrderAdapters(IAdapter adapterOne, IAdapter adapterTwo); error DuplicateThreashold(uint256 threshold); error InvalidAdapter(IAdapter adapter); + error InvalidThreshold(uint256 threshold); error NoAdaptersEnabled(uint256 domain); error NoAdaptersGiven(); error ThresholdNotMet(); diff --git a/packages/evm/contracts/ownable/GiriGiriBashi.sol b/packages/evm/contracts/ownable/GiriGiriBashi.sol index fb3aac56..1606b877 100644 --- a/packages/evm/contracts/ownable/GiriGiriBashi.sol +++ b/packages/evm/contracts/ownable/GiriGiriBashi.sol @@ -23,7 +23,7 @@ contract GiriGiriBashi is IGiriGiriBashi, ShuSo { } modifier zeroCount(uint256 domain) { - if (domains[domain].count != 0) revert CountMustBeZero(domain); + if (domains[domain].count != 0 && domains[domain].threshold > 0) revert CountMustBeZero(domain); _; } diff --git a/packages/evm/contracts/ownable/ShuSo.sol b/packages/evm/contracts/ownable/ShuSo.sol index 5c03fecf..78dba4fb 100644 --- a/packages/evm/contracts/ownable/ShuSo.sol +++ b/packages/evm/contracts/ownable/ShuSo.sol @@ -202,11 +202,11 @@ abstract contract ShuSo is IShuSho, OwnableUpgradeable { * @param threshold - Uint256 threshold to set for the given domain. * @notice Only callable by the owner of this contract. * @notice Reverts if threshold is already set to the given value. - * @notice It's IMPORTANT to set the threshold greater than or equal to _adapters.length + 1. - * Setting it lower would mean that the return value of _getThresholdHash - * would depend on the order of the adapters. */ function _setThreshold(uint256 domain, uint256 threshold) internal onlyOwner { + uint256 count = domains[domain].count; + if (count == 0) revert CountCannotBeZero(); + if (threshold < (count / 2) + 1) revert InvalidThreshold(threshold); if (domains[domain].threshold == threshold) revert DuplicateThreashold(threshold); domains[domain].threshold = threshold; emit ThresholdSet(domain, threshold); diff --git a/packages/evm/test/02_ShoyuBashi.spec.ts b/packages/evm/test/02_ShoyuBashi.spec.ts index af46d28f..3e54f5d4 100644 --- a/packages/evm/test/02_ShoyuBashi.spec.ts +++ b/packages/evm/test/02_ShoyuBashi.spec.ts @@ -22,7 +22,6 @@ const setup = async () => { await mockAdapter.setHashes(DOMAIN_ID, [0, 1, 2], [HASH_ZERO, HASH_GOOD, HASH_GOOD]) await anotherAdapter.setHashes(DOMAIN_ID, [0, 1, 2], [HASH_ZERO, HASH_GOOD, HASH_BAD]) - await shoyuBashi.setThreshold(DOMAIN_ID, 2) return { wallet, @@ -81,6 +80,8 @@ describe("ShoyuBashi", function () { }) it("Reverts if threshold is already set", async function () { const { shoyuBashi } = await setup() + await shoyuBashi.enableAdapters(DOMAIN_ID, [ADDRESS_TWO, ADDRESS_THREE]) + await shoyuBashi.setThreshold(DOMAIN_ID, 2) await expect(shoyuBashi.setThreshold(DOMAIN_ID, 2)).to.be.revertedWithCustomError( shoyuBashi, "DuplicateThreashold", @@ -88,12 +89,14 @@ describe("ShoyuBashi", function () { }) it("Sets threshold for the given ChainID", async function () { const { shoyuBashi } = await setup() - expect(await shoyuBashi.setThreshold(DOMAIN_ID, 3)) - expect((await shoyuBashi.domains(DOMAIN_ID)).threshold).to.equal(3) + await shoyuBashi.enableAdapters(DOMAIN_ID, [ADDRESS_TWO, ADDRESS_THREE]) + expect(await shoyuBashi.setThreshold(DOMAIN_ID, 2)) + expect((await shoyuBashi.domains(DOMAIN_ID)).threshold).to.equal(2) }) it("Emits HashiSet() event", async function () { const { shoyuBashi } = await setup() - await expect(shoyuBashi.setThreshold(DOMAIN_ID, 3)).to.emit(shoyuBashi, "ThresholdSet").withArgs(DOMAIN_ID, 3) + await shoyuBashi.enableAdapters(DOMAIN_ID, [ADDRESS_TWO, ADDRESS_THREE]) + await expect(shoyuBashi.setThreshold(DOMAIN_ID, 2)).to.emit(shoyuBashi, "ThresholdSet").withArgs(DOMAIN_ID, 2) }) }) @@ -246,9 +249,9 @@ describe("ShoyuBashi", function () { it("Returns threshold and count", async function () { const { shoyuBashi } = await setup() await shoyuBashi.enableAdapters(DOMAIN_ID, [ADDRESS_TWO, ADDRESS_THREE]) - await shoyuBashi.setThreshold(DOMAIN_ID, 1) + await shoyuBashi.setThreshold(DOMAIN_ID, 2) const [threshold] = await shoyuBashi.getThresholdAndCount(DOMAIN_ID) - await expect(threshold).to.equal(1) + await expect(threshold).to.equal(2) }) }) @@ -263,6 +266,7 @@ describe("ShoyuBashi", function () { it("Reverts if threshold is not met", async function () { const { shoyuBashi, mockAdapter } = await setup() await shoyuBashi.enableAdapters(DOMAIN_ID, [mockAdapter.address]) + await shoyuBashi.setThreshold(DOMAIN_ID, 2) await expect(shoyuBashi.getUnanimousHash(DOMAIN_ID, 1)).to.be.revertedWithCustomError( shoyuBashi, "ThresholdNotMet", @@ -286,6 +290,7 @@ describe("ShoyuBashi", function () { it("Reverts if threshold is not met", async function () { const { shoyuBashi, mockAdapter, anotherAdapter } = await setup() await shoyuBashi.enableAdapters(DOMAIN_ID, [mockAdapter.address, anotherAdapter.address]) + await shoyuBashi.setThreshold(DOMAIN_ID, 3) await expect(shoyuBashi.getThresholdHash(DOMAIN_ID, 2)).to.be.revertedWithCustomError( shoyuBashi, "ThresholdNotMet", @@ -310,6 +315,7 @@ describe("ShoyuBashi", function () { it("Reverts if threshold is not met", async function () { const { shoyuBashi, mockAdapter } = await setup() await shoyuBashi.enableAdapters(DOMAIN_ID, [mockAdapter.address]) + await shoyuBashi.setThreshold(DOMAIN_ID, 2) await expect(shoyuBashi.getHash(DOMAIN_ID, 1, [mockAdapter.address])).to.be.revertedWithCustomError( shoyuBashi, "ThresholdNotMet", diff --git a/packages/evm/test/03_GiriGiriBashi.spec.ts b/packages/evm/test/03_GiriGiriBashi.spec.ts index 8fc61060..28aa14ed 100644 --- a/packages/evm/test/03_GiriGiriBashi.spec.ts +++ b/packages/evm/test/03_GiriGiriBashi.spec.ts @@ -49,7 +49,7 @@ const setup = async (_configs?: any) => { [0, 1, 20, 21, 22], [HASH_ZERO, HASH_GOOD, HASH_DEAD, HASH_GOOD, HASH_GOOD], ) - await giriGiriBashi.setThreshold(DOMAIN_ID, _configs?.threshold || 2) + await giriGiriBashi.setChallengeRange(DOMAIN_ID, CHALLENGE_RANGE) const settings = { @@ -111,21 +111,50 @@ describe("GiriGiriBashi", function () { it("Reverts if count is greater than zero", async function () { const { giriGiriBashi, mockAdapter, settings } = await setup() await giriGiriBashi.enableAdapters(DOMAIN_ID, [mockAdapter.address], [settings]) + await giriGiriBashi.setThreshold(DOMAIN_ID, 2) await expect(giriGiriBashi.setThreshold(DOMAIN_ID, 2)).to.be.revertedWithCustomError( giriGiriBashi, "CountMustBeZero", ) }) - it("Sets threshold for the given ChainID", async function () { + it("Reverts if adapters are not enabled", async function () { const { giriGiriBashi } = await setup() - expect(await giriGiriBashi.setThreshold(DOMAIN_ID, 3)) - expect((await giriGiriBashi.domains(DOMAIN_ID)).threshold).to.equal(3) + await expect(giriGiriBashi.setThreshold(DOMAIN_ID, 2)).to.be.revertedWithCustomError( + giriGiriBashi, + "CountCannotBeZero", + ) + }) + it("Reverts if the threshold is less than them majority of adapters", async function () { + const { giriGiriBashi, settings, mockAdapter, secondMockAdapter, thirdMockAdapter } = await setup() + await giriGiriBashi.enableAdapters( + DOMAIN_ID, + [mockAdapter.address, secondMockAdapter.address, thirdMockAdapter.address], + [settings, settings, settings], + ) + await expect(giriGiriBashi.setThreshold(DOMAIN_ID, 1)) + .to.be.revertedWithCustomError(giriGiriBashi, "InvalidThreshold") + .withArgs(1) + }) + it("Sets threshold for the given ChainID", async function () { + const { giriGiriBashi, mockAdapter, secondMockAdapter, settings } = await setup() + await giriGiriBashi.enableAdapters( + DOMAIN_ID, + [mockAdapter.address, secondMockAdapter.address], + [settings, settings], + ) + await giriGiriBashi.setThreshold(DOMAIN_ID, 2) + expect((await giriGiriBashi.domains(DOMAIN_ID)).threshold).to.equal(2) }) it("Emits HashiSet() event", async function () { - const { giriGiriBashi } = await setup() - await expect(giriGiriBashi.setThreshold(DOMAIN_ID, 3)) + const { giriGiriBashi, mockAdapter, secondMockAdapter, settings } = await setup() + await giriGiriBashi.enableAdapters( + DOMAIN_ID, + [mockAdapter.address, secondMockAdapter.address], + [settings, settings], + ) + await expect(giriGiriBashi.setThreshold(DOMAIN_ID, 2)) .to.emit(giriGiriBashi, "ThresholdSet") - .withArgs(DOMAIN_ID, 3) + .withArgs(DOMAIN_ID, 2) }) }) @@ -139,7 +168,8 @@ describe("GiriGiriBashi", function () { }) it("Reverts if any adapters are already enabled", async function () { const { giriGiriBashi, settings } = await setup() - await expect(giriGiriBashi.enableAdapters(DOMAIN_ID, [ADDRESS_TWO], [settings])) + await giriGiriBashi.enableAdapters(DOMAIN_ID, [ADDRESS_TWO], [settings]) + await giriGiriBashi.setThreshold(DOMAIN_ID, 1) await expect(giriGiriBashi.enableAdapters(DOMAIN_ID, [ADDRESS_TWO], [settings])).to.be.revertedWithCustomError( giriGiriBashi, "CountMustBeZero", @@ -153,7 +183,8 @@ describe("GiriGiriBashi", function () { }) it("Enables the given adapters", async function () { const { giriGiriBashi, settings } = await setup() - await expect(giriGiriBashi.enableAdapters(DOMAIN_ID, [ADDRESS_TWO, ADDRESS_THREE], [settings, settings])) + await giriGiriBashi.enableAdapters(DOMAIN_ID, [ADDRESS_TWO, ADDRESS_THREE], [settings, settings]) + await giriGiriBashi.setThreshold(DOMAIN_ID, 2) const adapters = await giriGiriBashi.getAdapters(DOMAIN_ID) await expect(adapters[0]).to.equal(ADDRESS_TWO) await expect(adapters[1]).to.equal(ADDRESS_THREE) @@ -194,8 +225,8 @@ describe("GiriGiriBashi", function () { }) it("Disables the given adapters", async function () { const { giriGiriBashi, settings } = await setup() - await giriGiriBashi.setThreshold(DOMAIN_ID, ethers.constants.MaxUint256) await giriGiriBashi.enableAdapters(DOMAIN_ID, [ADDRESS_TWO, ADDRESS_THREE], [settings, settings]) + await giriGiriBashi.setThreshold(DOMAIN_ID, ethers.constants.MaxUint256) await giriGiriBashi.disableAdapters(DOMAIN_ID, [ADDRESS_TWO, ADDRESS_THREE]) const adapters = await giriGiriBashi.getAdapters(DOMAIN_ID) await expect(adapters[0]).to.equal(undefined) @@ -210,6 +241,7 @@ describe("GiriGiriBashi", function () { [mockAdapter.address, secondMockAdapter.address], [settings, settings], ) + await giriGiriBashi.setThreshold(DOMAIN_ID, 2) const oldHead = await giriGiriBashi.heads(DOMAIN_ID) await giriGiriBashi.getUnanimousHash(DOMAIN_ID, 1) const newHead = await giriGiriBashi.heads(DOMAIN_ID) @@ -218,14 +250,15 @@ describe("GiriGiriBashi", function () { }) describe("getThresholdHash()", function () { - for (let threshold = 1; threshold <= 3; threshold++) { + for (let threshold = 2; threshold <= 3; threshold++) { it(`Updates head for given domain with ${threshold}/3`, async function () { - const { giriGiriBashi, mockAdapter, secondMockAdapter, thirdMockAdapter, settings } = await setup({ threshold }) + const { giriGiriBashi, mockAdapter, secondMockAdapter, thirdMockAdapter, settings } = await setup() await giriGiriBashi.enableAdapters( DOMAIN_ID, [mockAdapter.address, secondMockAdapter.address, thirdMockAdapter.address], [settings, settings, settings], ) + await giriGiriBashi.setThreshold(DOMAIN_ID, threshold) const oldHead = await giriGiriBashi.heads(DOMAIN_ID) expect(await giriGiriBashi.callStatic.getThresholdHash(DOMAIN_ID, 1)).to.equal(HASH_GOOD) await giriGiriBashi.getThresholdHash(DOMAIN_ID, 1) @@ -243,6 +276,7 @@ describe("GiriGiriBashi", function () { [mockAdapter.address, secondMockAdapter.address], [settings, settings], ) + await giriGiriBashi.setThreshold(DOMAIN_ID, 2) let adapters if (secondMockAdapter.address > mockAdapter.address) { adapters = [mockAdapter.address, secondMockAdapter.address] @@ -270,6 +304,7 @@ describe("GiriGiriBashi", function () { [mockAdapter.address, secondMockAdapter.address], [settings, settings], ) + await giriGiriBashi.setThreshold(DOMAIN_ID, 2) await expect(giriGiriBashi.challengeAdapter(DOMAIN_ID, 1, mockAdapter.address)) .to.be.revertedWithCustomError(giriGiriBashi, "NotEnoughValue") .withArgs(mockAdapter.address, 0) @@ -278,6 +313,7 @@ describe("GiriGiriBashi", function () { const { giriGiriBashi, mockAdapter, secondMockAdapter, settings } = await setup() const adapters = [mockAdapter.address, secondMockAdapter.address].sort(compareAddresses) await giriGiriBashi.enableAdapters(DOMAIN_ID, adapters, [settings, settings]) + await giriGiriBashi.setThreshold(DOMAIN_ID, 2) await giriGiriBashi.getHash(DOMAIN_ID, 21, adapters) const head = await giriGiriBashi.heads(DOMAIN_ID) @@ -304,6 +340,7 @@ describe("GiriGiriBashi", function () { const { giriGiriBashi, mockAdapter, secondMockAdapter, settings } = await setup() const adapters = [mockAdapter.address, secondMockAdapter.address].sort(compareAddresses) await giriGiriBashi.enableAdapters(DOMAIN_ID, adapters, [settings, settings]) + await giriGiriBashi.setThreshold(DOMAIN_ID, 2) await giriGiriBashi.getHash(DOMAIN_ID, 21, adapters) const head = await giriGiriBashi.heads(DOMAIN_ID) @@ -347,6 +384,7 @@ describe("GiriGiriBashi", function () { const { giriGiriBashi, mockAdapter, secondMockAdapter, settings } = await setup() const adapters = [mockAdapter.address, secondMockAdapter.address].sort(compareAddresses) await giriGiriBashi.enableAdapters(DOMAIN_ID, adapters, [settings, settings]) + await giriGiriBashi.setThreshold(DOMAIN_ID, 2) await giriGiriBashi.getHash(DOMAIN_ID, 21, adapters) const head = await giriGiriBashi.heads(DOMAIN_ID) expect( @@ -364,6 +402,7 @@ describe("GiriGiriBashi", function () { const { giriGiriBashi, mockAdapter, secondMockAdapter, settings } = await setup() const adapters = [mockAdapter.address, secondMockAdapter.address].sort(compareAddresses) await giriGiriBashi.enableAdapters(DOMAIN_ID, adapters, [settings, settings]) + await giriGiriBashi.setThreshold(DOMAIN_ID, 2) await giriGiriBashi.getHash(DOMAIN_ID, 21, adapters) const head = await giriGiriBashi.heads(DOMAIN_ID) @@ -403,6 +442,7 @@ describe("GiriGiriBashi", function () { const { giriGiriBashi, mockAdapter, secondMockAdapter, settings } = await setup() const adapters = [mockAdapter.address, secondMockAdapter.address].sort(compareAddresses) await giriGiriBashi.enableAdapters(DOMAIN_ID, adapters, [settings, settings]) + await giriGiriBashi.setThreshold(DOMAIN_ID, 2) await giriGiriBashi.getHash(DOMAIN_ID, 21, adapters) const head = await giriGiriBashi.heads(DOMAIN_ID) @@ -416,6 +456,7 @@ describe("GiriGiriBashi", function () { const { giriGiriBashi, mockAdapter, secondMockAdapter, settings } = await setup() const adapters = [mockAdapter.address, secondMockAdapter.address].sort(compareAddresses) await giriGiriBashi.enableAdapters(DOMAIN_ID, adapters, [settings, settings]) + await giriGiriBashi.setThreshold(DOMAIN_ID, 2) await giriGiriBashi.getHash(DOMAIN_ID, 21, adapters) const head = await giriGiriBashi.heads(DOMAIN_ID) @@ -438,6 +479,7 @@ describe("GiriGiriBashi", function () { const { giriGiriBashi, mockAdapter, secondMockAdapter, settings } = await setup() const adapters = [mockAdapter.address, secondMockAdapter.address].sort(compareAddresses) await giriGiriBashi.enableAdapters(DOMAIN_ID, adapters, [settings, settings]) + await giriGiriBashi.setThreshold(DOMAIN_ID, 2) await giriGiriBashi.getHash(DOMAIN_ID, 21, adapters) const head = await giriGiriBashi.heads(DOMAIN_ID) @@ -459,6 +501,7 @@ describe("GiriGiriBashi", function () { const { giriGiriBashi, mockAdapter, secondMockAdapter, settings, wallet } = await setup() const adapters = [mockAdapter.address, secondMockAdapter.address].sort(compareAddresses) await giriGiriBashi.enableAdapters(DOMAIN_ID, adapters, [settings, settings]) + await giriGiriBashi.setThreshold(DOMAIN_ID, 2) await giriGiriBashi.getHash(DOMAIN_ID, 21, adapters) const head = await giriGiriBashi.heads(DOMAIN_ID) const challengeBlock = head - CHALLENGE_RANGE + 1 @@ -486,6 +529,7 @@ describe("GiriGiriBashi", function () { const { giriGiriBashi, mockAdapter, secondMockAdapter, settings } = await setup() const adapters = [mockAdapter.address, secondMockAdapter.address].sort(compareAddresses) await giriGiriBashi.enableAdapters(DOMAIN_ID, adapters, [settings, settings]) + await giriGiriBashi.setThreshold(DOMAIN_ID, 2) await giriGiriBashi.getHash(DOMAIN_ID, 1, adapters) const head = await giriGiriBashi.heads(DOMAIN_ID) @@ -494,9 +538,6 @@ describe("GiriGiriBashi", function () { value: BOND, }) - await mockAdapter.setHashes(DOMAIN_ID, [challengeBlock], [HASH_GOOD]) - await secondMockAdapter.setHashes(DOMAIN_ID, [challengeBlock], [HASH_GOOD]) - const balanceBefore = await ethers.provider.getBalance(ADDRESS_TWO) await giriGiriBashi.resolveChallenge(DOMAIN_ID, challengeBlock, mockAdapter.address, [secondMockAdapter.address]) expect(await ethers.provider.getBalance(ADDRESS_TWO)).to.equal(balanceBefore.add(BOND)) @@ -507,6 +548,7 @@ describe("GiriGiriBashi", function () { const { giriGiriBashi, mockAdapter, secondMockAdapter, settings, hashi } = await setup() const adapters = [mockAdapter.address, secondMockAdapter.address].sort(compareAddresses) await giriGiriBashi.enableAdapters(DOMAIN_ID, adapters, [settings, settings]) + await giriGiriBashi.setThreshold(DOMAIN_ID, 2) await giriGiriBashi.getHash(DOMAIN_ID, 21, adapters) const head = await giriGiriBashi.heads(DOMAIN_ID) @@ -525,6 +567,7 @@ describe("GiriGiriBashi", function () { const { giriGiriBashi, mockAdapter, secondMockAdapter, thirdMockAdapter, settings } = await setup() let adapters = [mockAdapter.address, secondMockAdapter.address, thirdMockAdapter.address] await giriGiriBashi.enableAdapters(DOMAIN_ID, adapters, [settings, settings, settings]) + await giriGiriBashi.setThreshold(DOMAIN_ID, 2) adapters = adapters.sort(compareAddresses) await giriGiriBashi.getHash(DOMAIN_ID, 1, adapters) @@ -550,6 +593,7 @@ describe("GiriGiriBashi", function () { const { giriGiriBashi, mockAdapter, secondMockAdapter, thirdMockAdapter, settings } = await setup() let adapters = [mockAdapter.address, secondMockAdapter.address, thirdMockAdapter.address] await giriGiriBashi.enableAdapters(DOMAIN_ID, adapters, [settings, settings, settings]) + await giriGiriBashi.setThreshold(DOMAIN_ID, 2) adapters = adapters.sort(compareAddresses) await giriGiriBashi.getHash(DOMAIN_ID, 21, adapters) @@ -572,6 +616,7 @@ describe("GiriGiriBashi", function () { const { giriGiriBashi, mockAdapter, secondMockAdapter, thirdMockAdapter, settings } = await setup() let adapters = [mockAdapter.address, secondMockAdapter.address, thirdMockAdapter.address] await giriGiriBashi.enableAdapters(DOMAIN_ID, adapters, [settings, settings, settings]) + await giriGiriBashi.setThreshold(DOMAIN_ID, 2) adapters = adapters.sort(compareAddresses) await giriGiriBashi.getHash(DOMAIN_ID, 21, adapters) @@ -599,6 +644,7 @@ describe("GiriGiriBashi", function () { const { giriGiriBashi, mockAdapter, secondMockAdapter, thirdMockAdapter, settings, wallet } = await setup() const adapters = [mockAdapter.address, secondMockAdapter.address, thirdMockAdapter.address].sort(compareAddresses) await giriGiriBashi.enableAdapters(DOMAIN_ID, adapters, [settings, settings, settings]) + await giriGiriBashi.setThreshold(DOMAIN_ID, 2) await giriGiriBashi.getHash(DOMAIN_ID, 21, adapters) const head = await giriGiriBashi.heads(DOMAIN_ID) @@ -626,6 +672,7 @@ describe("GiriGiriBashi", function () { const { giriGiriBashi, mockAdapter, secondMockAdapter, thirdMockAdapter, settings } = await setup() const adapters = [mockAdapter.address, secondMockAdapter.address, thirdMockAdapter.address].sort(compareAddresses) await giriGiriBashi.enableAdapters(DOMAIN_ID, adapters, [settings, settings, settings]) + await giriGiriBashi.setThreshold(DOMAIN_ID, 2) await expect(giriGiriBashi.callStatic.declareNoConfidence(DOMAIN_ID, 20, [mockAdapter.address])) .to.be.revertedWithCustomError(giriGiriBashi, "CannotProveNoConfidence") .withArgs(DOMAIN_ID, 20, [mockAdapter.address]) @@ -635,6 +682,7 @@ describe("GiriGiriBashi", function () { const adapters = [mockAdapter.address, secondMockAdapter.address, thirdMockAdapter.address].sort(compareAddresses) const adaptersThatAgree = [secondMockAdapter.address, thirdMockAdapter.address].sort(compareAddresses) await giriGiriBashi.enableAdapters(DOMAIN_ID, adapters, [settings, settings, settings]) + await giriGiriBashi.setThreshold(DOMAIN_ID, 2) await expect(giriGiriBashi.callStatic.declareNoConfidence(DOMAIN_ID, 22, adapters)) .to.be.revertedWithCustomError(giriGiriBashi, "AdaptersAgreed") .withArgs(adaptersThatAgree[0], adaptersThatAgree[1]) @@ -643,6 +691,7 @@ describe("GiriGiriBashi", function () { const { giriGiriBashi, mockAdapter, secondMockAdapter, thirdMockAdapter, settings } = await setup() const adapters = [mockAdapter.address, secondMockAdapter.address, thirdMockAdapter.address].sort(compareAddresses) await giriGiriBashi.enableAdapters(DOMAIN_ID, adapters, [settings, settings, settings]) + await giriGiriBashi.setThreshold(DOMAIN_ID, 2) expect(await giriGiriBashi.declareNoConfidence(DOMAIN_ID, 20, adapters)) const domain = await giriGiriBashi.domains(DOMAIN_ID) const challengeRange = await giriGiriBashi.challengeRanges(DOMAIN_ID) @@ -700,6 +749,7 @@ describe("GiriGiriBashi", function () { [mockAdapter.address, secondMockAdapter.address], [settings, settings], ) + await giriGiriBashi.setThreshold(DOMAIN_ID, 2) await expect( giriGiriBashi.replaceQuarantinedAdapters( DOMAIN_ID, @@ -732,6 +782,7 @@ describe("GiriGiriBashi", function () { [mockAdapter.address, secondMockAdapter.address], [settings, settings], ) + await giriGiriBashi.setThreshold(DOMAIN_ID, 2) await expect( giriGiriBashi.replaceQuarantinedAdapters( DOMAIN_ID, @@ -745,6 +796,7 @@ describe("GiriGiriBashi", function () { const { giriGiriBashi, mockAdapter, secondMockAdapter, thirdMockAdapter, settings } = await setup() let adapters = [mockAdapter.address, secondMockAdapter.address, thirdMockAdapter.address] await giriGiriBashi.enableAdapters(DOMAIN_ID, adapters, [settings, settings, settings]) + await giriGiriBashi.setThreshold(DOMAIN_ID, 2) adapters = adapters.sort(compareAddresses) await giriGiriBashi.getHash(DOMAIN_ID, 21, adapters) From dc5626193f17d99d3150ffaa49a0efc9121127ab Mon Sep 17 00:00:00 2001 From: Alessandro Manfredi Date: Tue, 20 Feb 2024 16:37:54 +0100 Subject: [PATCH 09/12] fix(contracts & test): fixes declareNoConfidence --- .../evm/contracts/interfaces/IGiriGiriBashi.sol | 2 +- packages/evm/contracts/ownable/GiriGiriBashi.sol | 16 ++++++++++------ packages/evm/test/03_GiriGiriBashi.spec.ts | 8 ++++---- 3 files changed, 15 insertions(+), 11 deletions(-) diff --git a/packages/evm/contracts/interfaces/IGiriGiriBashi.sol b/packages/evm/contracts/interfaces/IGiriGiriBashi.sol index 32d60d2a..4a3703a8 100644 --- a/packages/evm/contracts/interfaces/IGiriGiriBashi.sol +++ b/packages/evm/contracts/interfaces/IGiriGiriBashi.sol @@ -26,7 +26,7 @@ interface IGiriGiriBashi is IShuSho { error AdaptersCannotContainChallengedAdapter(IAdapter[] adapters, IAdapter adapter); error AdapterHasNotYetTimedOut(IAdapter adapter); error AdapterNotQuarantined(IAdapter adapter); - error AdaptersAgreed(IAdapter adapter1, IAdapter adapter2); + error AdaptersAgreed(); error AlreadyQuarantined(IAdapter adapter); error CannotProveNoConfidence(uint256 domain, uint256 id, IAdapter[] adapters); error ChallengeNotFound(bytes32 challengeId, uint256 domain, uint256 id, IAdapter adapter); diff --git a/packages/evm/contracts/ownable/GiriGiriBashi.sol b/packages/evm/contracts/ownable/GiriGiriBashi.sol index 1606b877..1be375a7 100644 --- a/packages/evm/contracts/ownable/GiriGiriBashi.sol +++ b/packages/evm/contracts/ownable/GiriGiriBashi.sol @@ -72,17 +72,21 @@ contract GiriGiriBashi is IGiriGiriBashi, ShuSo { checkAdapterOrderAndValidity(domain, _adapters); (uint256 threshold, uint256 count) = getThresholdAndCount(domain); - // check that there are enough adapters to prove no confidence - uint256 confidence = (count - _adapters.length) + 1; - if (confidence >= threshold) revert CannotProveNoConfidence(domain, id, _adapters); + if (_adapters.length != count) revert CannotProveNoConfidence(domain, id, _adapters); bytes32[] memory hashes = new bytes32[](_adapters.length); for (uint256 i = 0; i < _adapters.length; i++) hashes[i] = _adapters[i].getHash(domain, id); - // prove that each member of _adapters disagrees - for (uint256 i = 0; i < hashes.length; i++) + for (uint256 i = 0; i < hashes.length; i++) { + uint256 count = 1; for (uint256 j = 0; j < hashes.length; j++) - if (hashes[i] == hashes[j] && i != j) revert AdaptersAgreed(_adapters[i], _adapters[j]); + if (hashes[i] == hashes[j] && i != j) { + count++; + if (count == threshold) { + revert AdaptersAgreed(); + } + } + } domains[domain].threshold = type(uint256).max; delete challengeRanges[domain]; diff --git a/packages/evm/test/03_GiriGiriBashi.spec.ts b/packages/evm/test/03_GiriGiriBashi.spec.ts index 28aa14ed..0d514bf7 100644 --- a/packages/evm/test/03_GiriGiriBashi.spec.ts +++ b/packages/evm/test/03_GiriGiriBashi.spec.ts @@ -680,12 +680,12 @@ describe("GiriGiriBashi", function () { it("Reverts if any of the provided adapters agree", async function () { const { giriGiriBashi, mockAdapter, secondMockAdapter, thirdMockAdapter, settings } = await setup() const adapters = [mockAdapter.address, secondMockAdapter.address, thirdMockAdapter.address].sort(compareAddresses) - const adaptersThatAgree = [secondMockAdapter.address, thirdMockAdapter.address].sort(compareAddresses) await giriGiriBashi.enableAdapters(DOMAIN_ID, adapters, [settings, settings, settings]) await giriGiriBashi.setThreshold(DOMAIN_ID, 2) - await expect(giriGiriBashi.callStatic.declareNoConfidence(DOMAIN_ID, 22, adapters)) - .to.be.revertedWithCustomError(giriGiriBashi, "AdaptersAgreed") - .withArgs(adaptersThatAgree[0], adaptersThatAgree[1]) + await expect(giriGiriBashi.callStatic.declareNoConfidence(DOMAIN_ID, 22, adapters)).to.be.revertedWithCustomError( + giriGiriBashi, + "AdaptersAgreed", + ) }) it("Clears state for domain", async function () { const { giriGiriBashi, mockAdapter, secondMockAdapter, thirdMockAdapter, settings } = await setup() From abb2861d81c241a01c63164c865a083223acd261 Mon Sep 17 00:00:00 2001 From: Alessandro Manfredi Date: Tue, 20 Feb 2024 17:04:30 +0100 Subject: [PATCH 10/12] fix(contracts & test): adds check to prevent declareNoConfidence when the majority of adapters report bytes32(0) --- .../evm/contracts/ownable/GiriGiriBashi.sol | 13 +++++++---- packages/evm/test/03_GiriGiriBashi.spec.ts | 23 +++++++++++++++---- 2 files changed, 27 insertions(+), 9 deletions(-) diff --git a/packages/evm/contracts/ownable/GiriGiriBashi.sol b/packages/evm/contracts/ownable/GiriGiriBashi.sol index 1be375a7..478ba547 100644 --- a/packages/evm/contracts/ownable/GiriGiriBashi.sol +++ b/packages/evm/contracts/ownable/GiriGiriBashi.sol @@ -75,14 +75,19 @@ contract GiriGiriBashi is IGiriGiriBashi, ShuSo { if (_adapters.length != count) revert CannotProveNoConfidence(domain, id, _adapters); bytes32[] memory hashes = new bytes32[](_adapters.length); - for (uint256 i = 0; i < _adapters.length; i++) hashes[i] = _adapters[i].getHash(domain, id); + uint256 zeroHashes = 0; + for (uint256 i = 0; i < _adapters.length; i++) { + hashes[i] = _adapters[i].getHash(domain, id); + if (hashes[i] == bytes32(0)) zeroHashes++; + if (zeroHashes == threshold) revert CannotProveNoConfidence(domain, id, _adapters); + } for (uint256 i = 0; i < hashes.length; i++) { - uint256 count = 1; + uint256 equalHashes = 1; for (uint256 j = 0; j < hashes.length; j++) if (hashes[i] == hashes[j] && i != j) { - count++; - if (count == threshold) { + equalHashes++; + if (equalHashes == threshold) { revert AdaptersAgreed(); } } diff --git a/packages/evm/test/03_GiriGiriBashi.spec.ts b/packages/evm/test/03_GiriGiriBashi.spec.ts index 0d514bf7..c053aa5f 100644 --- a/packages/evm/test/03_GiriGiriBashi.spec.ts +++ b/packages/evm/test/03_GiriGiriBashi.spec.ts @@ -38,16 +38,20 @@ const setup = async (_configs?: any) => { const secondMockAdapter = await MockAdapter.deploy() const thirdMockAdapter = await MockAdapter.deploy() - await mockAdapter.setHashes(DOMAIN_ID, [0, 1, 20, 21, 22], [HASH_ZERO, HASH_GOOD, HASH_BAD, HASH_GOOD, HASH_BAD]) + await mockAdapter.setHashes( + DOMAIN_ID, + [0, 1, 20, 21, 22, 23], + [HASH_ZERO, HASH_GOOD, HASH_BAD, HASH_GOOD, HASH_BAD, HASH_ZERO], + ) await secondMockAdapter.setHashes( DOMAIN_ID, - [0, 1, 20, 21, 22], - [HASH_ZERO, HASH_GOOD, HASH_GOOD, HASH_GOOD, HASH_GOOD], + [0, 1, 20, 21, 22, 23], + [HASH_ZERO, HASH_GOOD, HASH_GOOD, HASH_GOOD, HASH_GOOD, HASH_ZERO], ) await thirdMockAdapter.setHashes( DOMAIN_ID, - [0, 1, 20, 21, 22], - [HASH_ZERO, HASH_GOOD, HASH_DEAD, HASH_GOOD, HASH_GOOD], + [0, 1, 20, 21, 22, 23], + [HASH_ZERO, HASH_GOOD, HASH_DEAD, HASH_GOOD, HASH_GOOD, HASH_GOOD], ) await giriGiriBashi.setChallengeRange(DOMAIN_ID, CHALLENGE_RANGE) @@ -677,6 +681,15 @@ describe("GiriGiriBashi", function () { .to.be.revertedWithCustomError(giriGiriBashi, "CannotProveNoConfidence") .withArgs(DOMAIN_ID, 20, [mockAdapter.address]) }) + it("Reverts if the majority of adapters report the hash = 0", async function () { + const { giriGiriBashi, mockAdapter, secondMockAdapter, thirdMockAdapter, settings } = await setup() + const adapters = [mockAdapter.address, secondMockAdapter.address, thirdMockAdapter.address].sort(compareAddresses) + await giriGiriBashi.enableAdapters(DOMAIN_ID, adapters, [settings, settings, settings]) + await giriGiriBashi.setThreshold(DOMAIN_ID, 2) + await expect(giriGiriBashi.callStatic.declareNoConfidence(DOMAIN_ID, 25, adapters)) + .to.be.revertedWithCustomError(giriGiriBashi, "CannotProveNoConfidence") + .withArgs(DOMAIN_ID, 25, adapters) + }) it("Reverts if any of the provided adapters agree", async function () { const { giriGiriBashi, mockAdapter, secondMockAdapter, thirdMockAdapter, settings } = await setup() const adapters = [mockAdapter.address, secondMockAdapter.address, thirdMockAdapter.address].sort(compareAddresses) From d140155538a001b6b3e2cdfa56fc3251f130dbd5 Mon Sep 17 00:00:00 2001 From: Alessandro Manfredi Date: Wed, 21 Feb 2024 05:37:53 +0100 Subject: [PATCH 11/12] ref(contracts): sets solidity version to ^0.8.0 within the interfaces --- packages/evm/contracts/interfaces/IAdapter.sol | 2 +- packages/evm/contracts/interfaces/IBlockHashAdapter.sol | 2 +- packages/evm/contracts/interfaces/IGiriGiriBashi.sol | 2 +- packages/evm/contracts/interfaces/IHashi.sol | 2 +- packages/evm/contracts/interfaces/IHeaderStorage.sol | 2 +- packages/evm/contracts/interfaces/IJushin.sol | 2 +- packages/evm/contracts/interfaces/IMessage.sol | 2 +- packages/evm/contracts/interfaces/IMessageHashCalculator.sol | 2 +- packages/evm/contracts/interfaces/IMessageIdCalculator.sol | 2 +- packages/evm/contracts/interfaces/IReporter.sol | 2 +- packages/evm/contracts/interfaces/IShoyuBashi.sol | 2 +- packages/evm/contracts/interfaces/IShuSho.sol | 2 +- packages/evm/contracts/interfaces/IYaho.sol | 2 +- packages/evm/contracts/interfaces/IYaru.sol | 2 +- 14 files changed, 14 insertions(+), 14 deletions(-) diff --git a/packages/evm/contracts/interfaces/IAdapter.sol b/packages/evm/contracts/interfaces/IAdapter.sol index 11ecb4f7..72498484 100644 --- a/packages/evm/contracts/interfaces/IAdapter.sol +++ b/packages/evm/contracts/interfaces/IAdapter.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: LGPL-3.0-only -pragma solidity ^0.8.20; +pragma solidity ^0.8.0; /** * @title IAdapter diff --git a/packages/evm/contracts/interfaces/IBlockHashAdapter.sol b/packages/evm/contracts/interfaces/IBlockHashAdapter.sol index 9073c05b..a6a27ed6 100644 --- a/packages/evm/contracts/interfaces/IBlockHashAdapter.sol +++ b/packages/evm/contracts/interfaces/IBlockHashAdapter.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: LGPL-3.0-only -pragma solidity ^0.8.20; +pragma solidity ^0.8.0; import { IAdapter } from "./IAdapter.sol"; diff --git a/packages/evm/contracts/interfaces/IGiriGiriBashi.sol b/packages/evm/contracts/interfaces/IGiriGiriBashi.sol index 2b917028..20d31209 100644 --- a/packages/evm/contracts/interfaces/IGiriGiriBashi.sol +++ b/packages/evm/contracts/interfaces/IGiriGiriBashi.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: LGPL-3.0-only -pragma solidity ^0.8.20; +pragma solidity ^0.8.0; import { IAdapter } from "./IAdapter.sol"; import { IHashi } from "./IHashi.sol"; diff --git a/packages/evm/contracts/interfaces/IHashi.sol b/packages/evm/contracts/interfaces/IHashi.sol index fa883171..9af2e961 100644 --- a/packages/evm/contracts/interfaces/IHashi.sol +++ b/packages/evm/contracts/interfaces/IHashi.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: LGPL-3.0-only -pragma solidity ^0.8.20; +pragma solidity ^0.8.0; import { IAdapter } from "./IAdapter.sol"; diff --git a/packages/evm/contracts/interfaces/IHeaderStorage.sol b/packages/evm/contracts/interfaces/IHeaderStorage.sol index 126857b2..5da04a3d 100644 --- a/packages/evm/contracts/interfaces/IHeaderStorage.sol +++ b/packages/evm/contracts/interfaces/IHeaderStorage.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: LGPL-3.0-only -pragma solidity ^0.8.20; +pragma solidity ^0.8.0; /** * @title IHeaderStorage diff --git a/packages/evm/contracts/interfaces/IJushin.sol b/packages/evm/contracts/interfaces/IJushin.sol index 55aecb03..a8df2c76 100644 --- a/packages/evm/contracts/interfaces/IJushin.sol +++ b/packages/evm/contracts/interfaces/IJushin.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: LGPL-3.0-only -pragma solidity ^0.8.20; +pragma solidity ^0.8.0; /** * @title IJushin diff --git a/packages/evm/contracts/interfaces/IMessage.sol b/packages/evm/contracts/interfaces/IMessage.sol index 9ec02029..47babcc8 100644 --- a/packages/evm/contracts/interfaces/IMessage.sol +++ b/packages/evm/contracts/interfaces/IMessage.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: LGPL-3.0-only -pragma solidity ^0.8.20; +pragma solidity ^0.8.0; import { IReporter } from "./IReporter.sol"; import { IAdapter } from "./IAdapter.sol"; diff --git a/packages/evm/contracts/interfaces/IMessageHashCalculator.sol b/packages/evm/contracts/interfaces/IMessageHashCalculator.sol index acb10fd8..24a41ef3 100644 --- a/packages/evm/contracts/interfaces/IMessageHashCalculator.sol +++ b/packages/evm/contracts/interfaces/IMessageHashCalculator.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: LGPL-3.0-only -pragma solidity ^0.8.20; +pragma solidity ^0.8.0; import { Message } from "./IMessage.sol"; diff --git a/packages/evm/contracts/interfaces/IMessageIdCalculator.sol b/packages/evm/contracts/interfaces/IMessageIdCalculator.sol index ee818fec..0cfefee8 100644 --- a/packages/evm/contracts/interfaces/IMessageIdCalculator.sol +++ b/packages/evm/contracts/interfaces/IMessageIdCalculator.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: LGPL-3.0-only -pragma solidity ^0.8.20; +pragma solidity ^0.8.0; /** * @title IMessageIdCalculator diff --git a/packages/evm/contracts/interfaces/IReporter.sol b/packages/evm/contracts/interfaces/IReporter.sol index ced2048a..6f9ad316 100644 --- a/packages/evm/contracts/interfaces/IReporter.sol +++ b/packages/evm/contracts/interfaces/IReporter.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: LGPL-3.0-only -pragma solidity ^0.8.20; +pragma solidity ^0.8.0; import { IAdapter } from "./IAdapter.sol"; diff --git a/packages/evm/contracts/interfaces/IShoyuBashi.sol b/packages/evm/contracts/interfaces/IShoyuBashi.sol index 15f43f46..96a0ea9e 100644 --- a/packages/evm/contracts/interfaces/IShoyuBashi.sol +++ b/packages/evm/contracts/interfaces/IShoyuBashi.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: LGPL-3.0-only -pragma solidity ^0.8.20; +pragma solidity ^0.8.0; import { IHashi } from "./IHashi.sol"; import { IAdapter } from "./IAdapter.sol"; diff --git a/packages/evm/contracts/interfaces/IShuSho.sol b/packages/evm/contracts/interfaces/IShuSho.sol index 97feeecf..1ce17c4e 100644 --- a/packages/evm/contracts/interfaces/IShuSho.sol +++ b/packages/evm/contracts/interfaces/IShuSho.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: LGPL-3.0-only -pragma solidity ^0.8.20; +pragma solidity ^0.8.0; import { IHashi } from "./IHashi.sol"; import { IAdapter } from "./IAdapter.sol"; diff --git a/packages/evm/contracts/interfaces/IYaho.sol b/packages/evm/contracts/interfaces/IYaho.sol index b6d780ec..46f8edc1 100644 --- a/packages/evm/contracts/interfaces/IYaho.sol +++ b/packages/evm/contracts/interfaces/IYaho.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: LGPL-3.0-only -pragma solidity ^0.8.20; +pragma solidity ^0.8.0; import { IMessageHashCalculator } from "./IMessageHashCalculator.sol"; import { IMessageIdCalculator } from "./IMessageIdCalculator.sol"; diff --git a/packages/evm/contracts/interfaces/IYaru.sol b/packages/evm/contracts/interfaces/IYaru.sol index 77258293..150c62fe 100644 --- a/packages/evm/contracts/interfaces/IYaru.sol +++ b/packages/evm/contracts/interfaces/IYaru.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: LGPL-3.0-only -pragma solidity ^0.8.20; +pragma solidity ^0.8.0; import { Message } from "./IMessage.sol"; import { IMessageHashCalculator } from "./IMessageHashCalculator.sol"; From d8368cb8c49af20f03b61dbcba27fbd8a77c498c Mon Sep 17 00:00:00 2001 From: Alessandro Manfredi Date: Wed, 21 Feb 2024 07:03:48 +0100 Subject: [PATCH 12/12] ref(contracts & test): adds getter fxs within GiriGiriBashi and ShuSho --- .../contracts/interfaces/IGiriGiriBashi.sol | 29 ++++ packages/evm/contracts/interfaces/IShuSho.sol | 21 +++ .../evm/contracts/ownable/GiriGiriBashi.sol | 146 ++++++++++-------- packages/evm/contracts/ownable/ShoyuBashi.sol | 12 +- packages/evm/contracts/ownable/ShuSo.sol | 146 ++++++++++-------- packages/evm/test/02_ShoyuBashi.spec.ts | 14 +- packages/evm/test/03_GiriGiriBashi.spec.ts | 92 ++++++----- 7 files changed, 272 insertions(+), 188 deletions(-) diff --git a/packages/evm/contracts/interfaces/IGiriGiriBashi.sol b/packages/evm/contracts/interfaces/IGiriGiriBashi.sol index 4a3703a8..c11cc231 100644 --- a/packages/evm/contracts/interfaces/IGiriGiriBashi.sol +++ b/packages/evm/contracts/interfaces/IGiriGiriBashi.sol @@ -144,6 +144,13 @@ interface IGiriGiriBashi is IShuSho { */ function enableAdapters(uint256 domain, IAdapter[] memory adapters, Settings[] memory settings) external; + /** + * @dev Get the current challenge given a challengeId. + * @param challengeId - The Bytes32 identifier for the challenge. + * @return challenge - Challenge indicating the challenge parameters. + */ + function getChallenge(bytes32 challengeId) external view returns (Challenge memory); + /** * @dev Gets the challenge ID for a given domain, ID, and adapter. * @param domain - The Uint256 identifier for the domain. @@ -153,6 +160,13 @@ interface IGiriGiriBashi is IShuSho { */ function getChallengeId(uint256 domain, uint256 id, IAdapter adapter) external pure returns (bytes32); + /** + * @dev Get how far beyond the current highestId can be challenged. + * @param domain - The Uint256 identifier for the domain. + * @return range - Uint256 indicating the challenge range. + */ + function getChallengeRange(uint256 domain) external view returns (uint256); + /** * @dev Returns the hash agreed upon by a threshold of the enabled adapters. * @param domain - Uint256 identifier for the domain to query. @@ -188,6 +202,21 @@ interface IGiriGiriBashi is IShuSho { */ function getHash(uint256 domain, uint256 id, IAdapter[] memory adapters) external returns (bytes32); + /** + * @dev Returns the highest id reported for a given id + * @param domain - Uint256 identifier for the domain to query. + * @return id - Uint256 indicating the highest id reported. + */ + function getHead(uint256 domain) external view returns (uint256); + + /** + * @dev Get the current settings for a given adapter. + * @param domain - Uint256 identifier for the domain to query. + * @param adapter - The adapter. + * @return settings - The Settings for the given adapter. + */ + function getSettings(uint256 domain, IAdapter adapter) external view returns (Settings memory); + /** * @dev Replaces the quarantined adapters for a given domain with new adapters and settings. * @param domain - The Uint256 identifier for the domain. diff --git a/packages/evm/contracts/interfaces/IShuSho.sol b/packages/evm/contracts/interfaces/IShuSho.sol index c573ab43..31c81e3e 100644 --- a/packages/evm/contracts/interfaces/IShuSho.sol +++ b/packages/evm/contracts/interfaces/IShuSho.sol @@ -71,6 +71,14 @@ interface IShuSho { */ function checkAdapterOrderAndValidity(uint256 domain, IAdapter[] memory _adapters) external view; + /** + * @dev Get the previous and the next adapter given a domain and an adapter. + * @param domain - Uint256 identifier for the domain. + * @param adapter - IAdapter value for the adapter. + * @return link - The Link struct containing the previous and the next adapter. + */ + function getAdapterLink(uint256 domain, IAdapter adapter) external view returns (Link memory); + /** * @dev Returns an array of enabled adapters for a given domain. * @param domain - Uint256 identifier for the domain for which to list adapters. @@ -78,6 +86,13 @@ interface IShuSho { */ function getAdapters(uint256 domain) external view returns (IAdapter[] memory); + /** + * @dev Get the current configuration for a given domain. + * @param domain - Uint256 identifier for the domain. + * @return domain - The Domain struct containing the current configuration for a given domain. + */ + function getDomain(uint256 domain) external view returns (Domain memory); + /** * @dev Returns the threshold and count for a given domain. * @param domain - Uint256 identifier for the domain. @@ -86,4 +101,10 @@ interface IShuSho { * @notice If the threshold for a domain has not been set, or is explicitly set to 0, this function will return a threshold equal to the adapters count for the given domain. */ function getThresholdAndCount(uint256 domain) external view returns (uint256, uint256); + + /** + * @dev Returns the address of the specified Hashi. + * @return hashi - The Hashi address. + */ + function hashi() external view returns (IHashi); } diff --git a/packages/evm/contracts/ownable/GiriGiriBashi.sol b/packages/evm/contracts/ownable/GiriGiriBashi.sol index 478ba547..2b296413 100644 --- a/packages/evm/contracts/ownable/GiriGiriBashi.sol +++ b/packages/evm/contracts/ownable/GiriGiriBashi.sol @@ -7,49 +7,51 @@ import { IHashi } from "../interfaces/IHashi.sol"; import { IGiriGiriBashi } from "../interfaces/IGiriGiriBashi.sol"; contract GiriGiriBashi is IGiriGiriBashi, ShuSo { - address payable public bondRecipient; // address that bonds from unsuccessful challenges should be sent to. - mapping(uint256 => uint256) public heads; // highest Id reported. - mapping(uint256 => uint256) public challengeRanges; // how far beyond the current highestId can a challenged. - mapping(uint256 => mapping(IAdapter => Settings)) public settings; - mapping(bytes32 => Challenge) public challenges; // current challenges. + address payable public bondRecipient; + + mapping(uint256 => uint256) private _heads; + mapping(uint256 => uint256) private _challengeRanges; + mapping(uint256 => mapping(IAdapter => Settings)) private _settings; + mapping(bytes32 => Challenge) private _challenges; constructor(address _owner, address _hashi, address payable _bondRecipient) ShuSo(_owner, _hashi) { bondRecipient = _bondRecipient; } modifier noConfidence(uint256 domain) { - if (domains[domain].threshold != type(uint256).max) revert NoConfidenceRequired(); + if (getDomain(domain).threshold != type(uint256).max) revert NoConfidenceRequired(); _; } modifier zeroCount(uint256 domain) { - if (domains[domain].count != 0 && domains[domain].threshold > 0) revert CountMustBeZero(domain); + Domain memory domainConfigs = getDomain(domain); + if (domainConfigs.count != 0 && domainConfigs.threshold > 0) revert CountMustBeZero(domain); _; } /// @inheritdoc IGiriGiriBashi function challengeAdapter(uint256 domain, uint256 id, IAdapter adapter) public payable { - if (adapters[domain][adapter].previous == IAdapter(address(0))) revert AdapterNotEnabled(adapter); - if (msg.value < settings[domain][adapter].minimumBond) revert NotEnoughValue(adapter, msg.value); - if (settings[domain][adapter].quarantined) revert AlreadyQuarantined(adapter); + if (getAdapterLink(domain, adapter).previous == IAdapter(address(0))) revert AdapterNotEnabled(adapter); + if (msg.value < _settings[domain][adapter].minimumBond) revert NotEnoughValue(adapter, msg.value); + if (_settings[domain][adapter].quarantined) revert AlreadyQuarantined(adapter); bytes32 challengeId = getChallengeId(domain, id, adapter); - if (challenges[challengeId].challenger != address(0)) + if (_challenges[challengeId].challenger != address(0)) revert DuplicateChallenge(challengeId, domain, id, adapter); // check if id is lower than startId, revert if true. // check if id is less than highestId + challengeRange, revert if false // check if id is lower than highestId - idDepth, revert if true - uint256 challengeRange = challengeRanges[domain]; - uint256 idDepth = settings[domain][adapter].idDepth; - uint256 head = heads[domain]; + uint256 challengeRange = _challengeRanges[domain]; + uint256 idDepth = _settings[domain][adapter].idDepth; + uint256 head = _heads[domain]; if ( - id < settings[domain][adapter].startId || // before start id + id < _settings[domain][adapter].startId || // before start id (challengeRange != 0 && id >= head && id - head > challengeRange) || // over domain challenge range (idDepth != 0 && head > idDepth && id <= head - idDepth) // outside of adapter idDepth ) revert OutOfRange(adapter, id); - Challenge storage challenge = challenges[challengeId]; + Challenge storage challenge = _challenges[challengeId]; challenge.challenger = payable(msg.sender); challenge.timestamp = block.timestamp; challenge.bond = msg.value; @@ -60,26 +62,26 @@ contract GiriGiriBashi is IGiriGiriBashi, ShuSo { /// @inheritdoc IGiriGiriBashi function enableAdapters( uint256 domain, - IAdapter[] memory _adapters, - Settings[] memory _settings + IAdapter[] memory adapters, + Settings[] memory settings ) public zeroCount(domain) { - _enableAdapters(domain, _adapters); - initSettings(domain, _adapters, _settings); + _enableAdapters(domain, adapters); + initSettings(domain, adapters, settings); } /// @inheritdoc IGiriGiriBashi - function declareNoConfidence(uint256 domain, uint256 id, IAdapter[] memory _adapters) public { - checkAdapterOrderAndValidity(domain, _adapters); + function declareNoConfidence(uint256 domain, uint256 id, IAdapter[] memory adapters) public { + checkAdapterOrderAndValidity(domain, adapters); (uint256 threshold, uint256 count) = getThresholdAndCount(domain); - if (_adapters.length != count) revert CannotProveNoConfidence(domain, id, _adapters); + if (adapters.length != count) revert CannotProveNoConfidence(domain, id, adapters); - bytes32[] memory hashes = new bytes32[](_adapters.length); + bytes32[] memory hashes = new bytes32[](adapters.length); uint256 zeroHashes = 0; - for (uint256 i = 0; i < _adapters.length; i++) { - hashes[i] = _adapters[i].getHash(domain, id); + for (uint256 i = 0; i < adapters.length; i++) { + hashes[i] = adapters[i].getHash(domain, id); if (hashes[i] == bytes32(0)) zeroHashes++; - if (zeroHashes == threshold) revert CannotProveNoConfidence(domain, id, _adapters); + if (zeroHashes == threshold) revert CannotProveNoConfidence(domain, id, adapters); } for (uint256 i = 0; i < hashes.length; i++) { @@ -93,16 +95,26 @@ contract GiriGiriBashi is IGiriGiriBashi, ShuSo { } } - domains[domain].threshold = type(uint256).max; - delete challengeRanges[domain]; + _setDomainThreshold(domain, type(uint256).max); + delete _challengeRanges[domain]; emit NoConfidenceDeclared(domain); } /// @inheritdoc IGiriGiriBashi - function disableAdapters(uint256 domain, IAdapter[] memory _adapters) public noConfidence(domain) { - _disableAdapters(domain, _adapters); - if (domains[domain].count == 0) domains[domain].threshold = 0; + function disableAdapters(uint256 domain, IAdapter[] memory adapters) public noConfidence(domain) { + _disableAdapters(domain, adapters); + if (getDomain(domain).count == 0) _setDomainThreshold(domain, 0); + } + + /// @inheritdoc IGiriGiriBashi + function getSettings(uint256 domain, IAdapter adapter) external view returns (Settings memory) { + return _settings[domain][adapter]; + } + + /// @inheritdoc IGiriGiriBashi + function getChallenge(bytes32 challengeId) external view returns (Challenge memory) { + return _challenges[challengeId]; } /// @inheritdoc IGiriGiriBashi @@ -110,6 +122,16 @@ contract GiriGiriBashi is IGiriGiriBashi, ShuSo { challengeId = keccak256(abi.encodePacked(domain, id, adapter)); } + /// @inheritdoc IGiriGiriBashi + function getChallengeRange(uint256 domain) external view returns (uint256) { + return _challengeRanges[domain]; + } + + /// @inheritdoc IGiriGiriBashi + function getHead(uint256 domain) external view returns (uint256) { + return _heads[domain]; + } + /// @inheritdoc IGiriGiriBashi function getThresholdHash(uint256 domain, uint256 id) public returns (bytes32 hash) { hash = _getThresholdHash(domain, id); @@ -123,8 +145,8 @@ contract GiriGiriBashi is IGiriGiriBashi, ShuSo { } /// @inheritdoc IGiriGiriBashi - function getHash(uint256 domain, uint256 id, IAdapter[] memory _adapters) public returns (bytes32 hash) { - hash = _getHash(domain, id, _adapters); + function getHash(uint256 domain, uint256 id, IAdapter[] memory adapters) public returns (bytes32 hash) { + hash = _getHash(domain, id, adapters); updateHead(domain, id); } @@ -133,16 +155,16 @@ contract GiriGiriBashi is IGiriGiriBashi, ShuSo { uint256 domain, IAdapter[] memory currentAdapters, IAdapter[] memory newAdapters, - Settings[] memory _settings + Settings[] memory settings ) public onlyOwner { - if (currentAdapters.length != newAdapters.length || currentAdapters.length != _settings.length) + if (currentAdapters.length != newAdapters.length || currentAdapters.length != settings.length) revert UnequalArrayLengths(); for (uint256 i = 0; i < currentAdapters.length; i++) { - if (!settings[domain][currentAdapters[i]].quarantined) revert AdapterNotQuarantined(currentAdapters[i]); + if (!_settings[domain][currentAdapters[i]].quarantined) revert AdapterNotQuarantined(currentAdapters[i]); } _disableAdapters(domain, currentAdapters); _enableAdapters(domain, newAdapters); - initSettings(domain, newAdapters, _settings); + initSettings(domain, newAdapters, settings); } /// @inheritdoc IGiriGiriBashi @@ -150,22 +172,22 @@ contract GiriGiriBashi is IGiriGiriBashi, ShuSo { uint256 domain, uint256 id, IAdapter adapter, - IAdapter[] memory _adapters + IAdapter[] memory adapters ) public returns (bool success) { // check if challenge exists, revert if false bytes32 challengeId = getChallengeId(domain, id, adapter); - if (challenges[challengeId].challenger == address(0)) + if (_challenges[challengeId].challenger == address(0)) revert ChallengeNotFound(challengeId, domain, id, adapter); - for (uint256 i = 0; i < _adapters.length; ) { - if (_adapters[i] == adapter) revert AdaptersCannotContainChallengedAdapter(_adapters, adapter); + for (uint256 i = 0; i < adapters.length; ) { + if (adapters[i] == adapter) revert AdaptersCannotContainChallengedAdapter(adapters, adapter); unchecked { ++i; } } - Challenge storage challenge = challenges[challengeId]; - Settings storage adapterSettings = settings[domain][adapter]; + Challenge storage challenge = _challenges[challengeId]; + Settings storage adapterSettings = _settings[domain][adapter]; bytes32 storedHash = adapter.getHash(domain, id); if (storedHash == bytes32(0)) { @@ -175,19 +197,19 @@ contract GiriGiriBashi is IGiriGiriBashi, ShuSo { challenge.challenger.transfer(challenge.bond); success = true; } else { - // if _adapters + 1 equals threshold && _adapters + adapter report the same header - if (_adapters.length == domains[domain].threshold - 1) { - checkAdapterOrderAndValidity(domain, _adapters); - bytes32 canonicalHash = hashi.getHash(domain, id, _adapters); + // if adapters + 1 equals threshold && adapters + adapter report the same header + if (adapters.length == getDomain(domain).threshold - 1) { + checkAdapterOrderAndValidity(domain, adapters); + bytes32 canonicalHash = hashi.getHash(domain, id, adapters); if (canonicalHash == storedHash) { bondRecipient.transfer(challenge.bond); success = false; } else { - revert IHashi.AdaptersDisagree(adapter, _adapters[0]); + revert IHashi.AdaptersDisagree(adapter, adapters[0]); } } else { - // check if _adapters report the same header as adapter - bytes32 canonicalHash = getHash(domain, id, _adapters); + // check if adapters report the same header as adapter + bytes32 canonicalHash = getHash(domain, id, adapters); if (canonicalHash == storedHash) { bondRecipient.transfer(challenge.bond); success = false; @@ -213,8 +235,8 @@ contract GiriGiriBashi is IGiriGiriBashi, ShuSo { /// @inheritdoc IGiriGiriBashi function setChallengeRange(uint256 domain, uint256 range) public onlyOwner { - if (challengeRanges[domain] != 0) revert ChallengeRangeAlreadySet(domain); - challengeRanges[domain] = range; + if (_challengeRanges[domain] != 0) revert ChallengeRangeAlreadySet(domain); + _challengeRanges[domain] = range; emit ChallengeRangeUpdated(domain, range); } @@ -227,21 +249,21 @@ contract GiriGiriBashi is IGiriGiriBashi, ShuSo { _setThreshold(domain, threshold); } - function initSettings(uint256 domain, IAdapter[] memory _adapters, Settings[] memory _settings) private { - if (_adapters.length != _settings.length) revert UnequalArrayLengths(); + function initSettings(uint256 domain, IAdapter[] memory _adapters, Settings[] memory adapters) private { + if (_adapters.length != adapters.length) revert UnequalArrayLengths(); for (uint256 i = 0; i < _adapters.length; i++) { IAdapter adapter = _adapters[i]; - settings[domain][adapter].quarantined = false; - settings[domain][adapter].minimumBond = _settings[i].minimumBond; - settings[domain][adapter].startId = _settings[i].startId; - settings[domain][adapter].idDepth = _settings[i].idDepth; - settings[domain][adapter].timeout = _settings[i].timeout; - emit SettingsInitialized(domain, adapter, _settings[i]); + _settings[domain][adapter].quarantined = false; + _settings[domain][adapter].minimumBond = adapters[i].minimumBond; + _settings[domain][adapter].startId = adapters[i].startId; + _settings[domain][adapter].idDepth = adapters[i].idDepth; + _settings[domain][adapter].timeout = adapters[i].timeout; + emit SettingsInitialized(domain, adapter, adapters[i]); } } function updateHead(uint256 domain, uint256 id) private { - if (id > heads[domain]) heads[domain] = id; + if (id > _heads[domain]) _heads[domain] = id; emit NewHead(domain, id); } } diff --git a/packages/evm/contracts/ownable/ShoyuBashi.sol b/packages/evm/contracts/ownable/ShoyuBashi.sol index ee3e7837..7a6c5ae0 100644 --- a/packages/evm/contracts/ownable/ShoyuBashi.sol +++ b/packages/evm/contracts/ownable/ShoyuBashi.sol @@ -19,13 +19,13 @@ contract ShoyuBashi is IShoyuBashi, ShuSo { } /// @inheritdoc IShoyuBashi - function enableAdapters(uint256 domain, IAdapter[] memory _adapters) public { - _enableAdapters(domain, _adapters); + function enableAdapters(uint256 domain, IAdapter[] memory adapters) public { + _enableAdapters(domain, adapters); } /// @inheritdoc IShoyuBashi - function disableAdapters(uint256 domain, IAdapter[] memory _adapters) public { - _disableAdapters(domain, _adapters); + function disableAdapters(uint256 domain, IAdapter[] memory adapters) public { + _disableAdapters(domain, adapters); } /// @inheritdoc IShoyuBashi @@ -39,7 +39,7 @@ contract ShoyuBashi is IShoyuBashi, ShuSo { } /// @inheritdoc IShoyuBashi - function getHash(uint256 domain, uint256 id, IAdapter[] memory _adapters) public view returns (bytes32) { - return _getHash(domain, id, _adapters); + function getHash(uint256 domain, uint256 id, IAdapter[] memory adapters) public view returns (bytes32) { + return _getHash(domain, id, adapters); } } diff --git a/packages/evm/contracts/ownable/ShuSo.sol b/packages/evm/contracts/ownable/ShuSo.sol index 344b155c..da067e93 100644 --- a/packages/evm/contracts/ownable/ShuSo.sol +++ b/packages/evm/contracts/ownable/ShuSo.sol @@ -10,8 +10,8 @@ abstract contract ShuSo is IShuSho, OwnableUpgradeable { IAdapter internal constant LIST_END = IAdapter(address(0x1)); IHashi public hashi; - mapping(uint256 => mapping(IAdapter => Link)) public adapters; - mapping(uint256 => Domain) public domains; + mapping(uint256 => mapping(IAdapter => Link)) private _adapters; + mapping(uint256 => Domain) private _domains; constructor(address _owner, address _hashi) { bytes memory initParams = abi.encode(_owner, _hashi); @@ -27,28 +27,38 @@ abstract contract ShuSo is IShuSho, OwnableUpgradeable { } /// @inheritdoc IShuSho - function checkAdapterOrderAndValidity(uint256 domain, IAdapter[] memory _adapters) public view { - for (uint256 i = 0; i < _adapters.length; i++) { - IAdapter adapter = _adapters[i]; - if (i > 0 && adapter <= _adapters[i - 1]) revert DuplicateOrOutOfOrderAdapters(adapter, _adapters[i - 1]); - if (adapters[domain][adapter].next == IAdapter(address(0))) revert InvalidAdapter(adapter); + function checkAdapterOrderAndValidity(uint256 domain, IAdapter[] memory adapters) public view { + for (uint256 i = 0; i < adapters.length; i++) { + IAdapter adapter = adapters[i]; + if (i > 0 && adapter <= adapters[i - 1]) revert DuplicateOrOutOfOrderAdapters(adapter, adapters[i - 1]); + if (_adapters[domain][adapter].next == IAdapter(address(0))) revert InvalidAdapter(adapter); } } + /// @inheritdoc IShuSho + function getAdapterLink(uint256 domain, IAdapter adapter) public view returns (Link memory) { + return _adapters[domain][adapter]; + } + /// @inheritdoc IShuSho function getAdapters(uint256 domain) public view returns (IAdapter[] memory) { - IAdapter[] memory _adapters = new IAdapter[](domains[domain].count); - IAdapter currentAdapter = adapters[domain][LIST_END].next; - for (uint256 i = 0; i < _adapters.length; i++) { - _adapters[i] = currentAdapter; - currentAdapter = adapters[domain][currentAdapter].next; + IAdapter[] memory adapters = new IAdapter[](_domains[domain].count); + IAdapter currentAdapter = _adapters[domain][LIST_END].next; + for (uint256 i = 0; i < adapters.length; i++) { + adapters[i] = currentAdapter; + currentAdapter = _adapters[domain][currentAdapter].next; } - return _adapters; + return adapters; + } + + /// @inheritdoc IShuSho + function getDomain(uint256 domain) public view returns (Domain memory) { + return _domains[domain]; } /// @inheritdoc IShuSho function getThresholdAndCount(uint256 domain_) public view returns (uint256, uint256) { - Domain storage domain = domains[domain_]; + Domain storage domain = _domains[domain_]; uint256 threshold = domain.threshold; uint256 count = domain.count; if (threshold == 0) threshold = count; @@ -60,75 +70,75 @@ abstract contract ShuSo is IShuSho, OwnableUpgradeable { /** * @dev Disables the given adapters for a given domain. * @param domain - Uint256 identifier for the domain for which to set adapters. - * @param _adapters - Array of adapter addresses. - * @notice Reverts if _adapters are out of order or contain duplicates. + * @param adapters - Array of adapter addresses. + * @notice Reverts if adapters are out of order or contain duplicates. * @notice Only callable by the owner of this contract. */ - function _disableAdapters(uint256 domain, IAdapter[] memory _adapters) internal onlyOwner { - if (domains[domain].count == 0) revert NoAdaptersEnabled(domain); - if (_adapters.length == 0) revert NoAdaptersGiven(); - for (uint256 i = 0; i < _adapters.length; i++) { - IAdapter adapter = _adapters[i]; + function _disableAdapters(uint256 domain, IAdapter[] memory adapters) internal onlyOwner { + if (_domains[domain].count == 0) revert NoAdaptersEnabled(domain); + if (adapters.length == 0) revert NoAdaptersGiven(); + for (uint256 i = 0; i < adapters.length; i++) { + IAdapter adapter = adapters[i]; if (adapter == IAdapter(address(0)) || adapter == LIST_END) revert InvalidAdapter(adapter); - Link memory current = adapters[domain][adapter]; + Link memory current = _adapters[domain][adapter]; if (current.next == IAdapter(address(0))) revert AdapterNotEnabled(adapter); IAdapter next = current.next; IAdapter previous = current.previous; - adapters[domain][next].previous = previous; - adapters[domain][previous].next = next; - delete adapters[domain][adapter].next; - delete adapters[domain][adapter].previous; - domains[domain].count--; + _adapters[domain][next].previous = previous; + _adapters[domain][previous].next = next; + delete _adapters[domain][adapter].next; + delete _adapters[domain][adapter].previous; + _domains[domain].count--; } - emit AdaptersDisabled(domain, _adapters); + emit AdaptersDisabled(domain, adapters); } /** * @dev Enables the given adapters for a given domain. * @param domain - Uint256 identifier for the domain for which to set adapters. - * @param _adapters - Array of adapter addresses. - * @notice Reverts if _adapters are out of order or contain duplicates. + * @param adapters - Array of adapter addresses. + * @notice Reverts if adapters are out of order or contain duplicates. * @notice Only callable by the owner of this contract. */ - function _enableAdapters(uint256 domain, IAdapter[] memory _adapters) internal onlyOwner { - if (adapters[domain][LIST_END].next == IAdapter(address(0))) { - adapters[domain][LIST_END].next = LIST_END; - adapters[domain][LIST_END].previous = LIST_END; + function _enableAdapters(uint256 domain, IAdapter[] memory adapters) internal onlyOwner { + if (_adapters[domain][LIST_END].next == IAdapter(address(0))) { + _adapters[domain][LIST_END].next = LIST_END; + _adapters[domain][LIST_END].previous = LIST_END; } - if (_adapters.length == 0) revert NoAdaptersGiven(); - for (uint256 i = 0; i < _adapters.length; i++) { - IAdapter adapter = _adapters[i]; + if (adapters.length == 0) revert NoAdaptersGiven(); + for (uint256 i = 0; i < adapters.length; i++) { + IAdapter adapter = adapters[i]; if (adapter == IAdapter(address(0)) || adapter == LIST_END) revert InvalidAdapter(adapter); - if (adapters[domain][adapter].next != IAdapter(address(0))) revert AdapterAlreadyEnabled(adapter); - IAdapter previous = adapters[domain][LIST_END].previous; - adapters[domain][previous].next = adapter; - adapters[domain][adapter].previous = previous; - adapters[domain][LIST_END].previous = adapter; - adapters[domain][adapter].next = LIST_END; - domains[domain].count++; + if (_adapters[domain][adapter].next != IAdapter(address(0))) revert AdapterAlreadyEnabled(adapter); + IAdapter previous = _adapters[domain][LIST_END].previous; + _adapters[domain][previous].next = adapter; + _adapters[domain][adapter].previous = previous; + _adapters[domain][LIST_END].previous = adapter; + _adapters[domain][adapter].next = LIST_END; + _domains[domain].count++; } - emit AdaptersEnabled(domain, _adapters); + emit AdaptersEnabled(domain, adapters); } /** * @dev Returns the hash unanimously agreed upon by all of the given adapters. * @param domain - Uint256 identifier for the domain to query. * @param id - Uint256 identifier to query. - * @param _adapters - Array of adapter addresses to query. + * @param adapters - Array of adapter addresses to query. * @return hash - Bytes32 hash agreed upon by the adapters for the given domain. - * @notice _adapters must be in numerical order from smallest to largest and contain no duplicates. - * @notice Reverts if _adapters are out of order or contain duplicates. + * @notice adapters must be in numerical order from smallest to largest and contain no duplicates. + * @notice Reverts if adapters are out of order or contain duplicates. * @notice Reverts if adapters disagree. * @notice Revert if the adapters do not yet have the hash for the given ID. * @notice Reverts if no adapters are set for the given domain. */ - function _getHash(uint256 domain, uint256 id, IAdapter[] memory _adapters) internal view returns (bytes32) { + function _getHash(uint256 domain, uint256 id, IAdapter[] memory adapters) internal view returns (bytes32) { (uint256 threshold, uint256 count) = getThresholdAndCount(domain); - if (_adapters.length == 0) revert NoAdaptersGiven(); + if (adapters.length == 0) revert NoAdaptersGiven(); if (count == 0) revert NoAdaptersEnabled(domain); - if (_adapters.length < threshold) revert ThresholdNotMet(); - checkAdapterOrderAndValidity(domain, _adapters); - return hashi.getHash(domain, id, _adapters); + if (adapters.length < threshold) revert ThresholdNotMet(); + checkAdapterOrderAndValidity(domain, adapters); + return hashi.getHash(domain, id, adapters); } /** @@ -141,26 +151,26 @@ abstract contract ShuSo is IShuSho, OwnableUpgradeable { * @notice Reverts if no adapters are set for the given domain. */ function _getThresholdHash(uint256 domain, uint256 id) internal view returns (bytes32 hash) { - IAdapter[] memory _adapters = getAdapters(domain); + IAdapter[] memory adapters = getAdapters(domain); (uint256 threshold, uint256 count) = getThresholdAndCount(domain); if (count == 0) revert NoAdaptersEnabled(domain); - if (_adapters.length < threshold) revert ThresholdNotMet(); + if (adapters.length < threshold) revert ThresholdNotMet(); - bytes32[] memory hashes = new bytes32[](_adapters.length); - for (uint i = 0; i < _adapters.length; i++) { - try _adapters[i].getHash(domain, id) returns (bytes32 currentHash) { + bytes32[] memory hashes = new bytes32[](adapters.length); + for (uint256 i = 0; i < adapters.length; i++) { + try adapters[i].getHash(domain, id) returns (bytes32 currentHash) { hashes[i] = currentHash; } catch {} // solhint-disable no-empty-blocks } - for (uint i = 0; i < hashes.length; i++) { + for (uint256 i = 0; i < hashes.length; i++) { if (i > hashes.length - threshold) break; bytes32 baseHash = hashes[i]; if (baseHash == bytes32(0)) continue; uint256 num = 0; - for (uint j = i; j < hashes.length; j++) { + for (uint256 j = i; j < hashes.length; j++) { if (baseHash == hashes[j]) { num++; if (num == threshold) return hashes[i]; @@ -180,11 +190,11 @@ abstract contract ShuSo is IShuSho, OwnableUpgradeable { * @notice Reverts if no adapters are set for the given domain. */ function _getUnanimousHash(uint256 domain, uint256 id) internal view returns (bytes32 hash) { - IAdapter[] memory _adapters = getAdapters(domain); + IAdapter[] memory adapters = getAdapters(domain); (uint256 threshold, uint256 count) = getThresholdAndCount(domain); if (count == 0) revert NoAdaptersEnabled(domain); - if (_adapters.length < threshold) revert ThresholdNotMet(); - return hashi.getHash(domain, id, _adapters); + if (adapters.length < threshold) revert ThresholdNotMet(); + return hashi.getHash(domain, id, adapters); } /** @@ -206,11 +216,15 @@ abstract contract ShuSo is IShuSho, OwnableUpgradeable { * @notice Reverts if threshold is already set to the given value. */ function _setThreshold(uint256 domain, uint256 threshold) internal onlyOwner { - uint256 count = domains[domain].count; + uint256 count = _domains[domain].count; if (count == 0) revert CountCannotBeZero(); if (threshold < (count / 2) + 1) revert InvalidThreshold(threshold); - if (domains[domain].threshold == threshold) revert DuplicateThreashold(threshold); - domains[domain].threshold = threshold; + if (_domains[domain].threshold == threshold) revert DuplicateThreashold(threshold); + _domains[domain].threshold = threshold; emit ThresholdSet(domain, threshold); } + + function _setDomainThreshold(uint256 domainId, uint256 threshold) internal { + _domains[domainId].threshold = threshold; + } } diff --git a/packages/evm/test/02_ShoyuBashi.spec.ts b/packages/evm/test/02_ShoyuBashi.spec.ts index 3e54f5d4..747fb034 100644 --- a/packages/evm/test/02_ShoyuBashi.spec.ts +++ b/packages/evm/test/02_ShoyuBashi.spec.ts @@ -91,7 +91,7 @@ describe("ShoyuBashi", function () { const { shoyuBashi } = await setup() await shoyuBashi.enableAdapters(DOMAIN_ID, [ADDRESS_TWO, ADDRESS_THREE]) expect(await shoyuBashi.setThreshold(DOMAIN_ID, 2)) - expect((await shoyuBashi.domains(DOMAIN_ID)).threshold).to.equal(2) + expect((await shoyuBashi.getDomain(DOMAIN_ID)).threshold).to.equal(2) }) it("Emits HashiSet() event", async function () { const { shoyuBashi } = await setup() @@ -143,12 +143,12 @@ describe("ShoyuBashi", function () { const adapters = await shoyuBashi.getAdapters(DOMAIN_ID) await expect(adapters[0]).to.equal(ADDRESS_TWO) await expect(adapters[1]).to.equal(ADDRESS_THREE) - expect((await shoyuBashi.adapters(DOMAIN_ID, LIST_END)).next).to.equal(ADDRESS_TWO) - expect((await shoyuBashi.adapters(DOMAIN_ID, LIST_END)).previous).to.equal(ADDRESS_THREE) - expect((await shoyuBashi.adapters(DOMAIN_ID, ADDRESS_TWO)).next).to.equal(ADDRESS_THREE) - expect((await shoyuBashi.adapters(DOMAIN_ID, ADDRESS_TWO)).previous).to.equal(LIST_END) - expect((await shoyuBashi.adapters(DOMAIN_ID, ADDRESS_THREE)).next).to.equal(LIST_END) - expect((await shoyuBashi.adapters(DOMAIN_ID, ADDRESS_THREE)).previous).to.equal(ADDRESS_TWO) + expect((await shoyuBashi.getAdapterLink(DOMAIN_ID, LIST_END)).next).to.equal(ADDRESS_TWO) + expect((await shoyuBashi.getAdapterLink(DOMAIN_ID, LIST_END)).previous).to.equal(ADDRESS_THREE) + expect((await shoyuBashi.getAdapterLink(DOMAIN_ID, ADDRESS_TWO)).next).to.equal(ADDRESS_THREE) + expect((await shoyuBashi.getAdapterLink(DOMAIN_ID, ADDRESS_TWO)).previous).to.equal(LIST_END) + expect((await shoyuBashi.getAdapterLink(DOMAIN_ID, ADDRESS_THREE)).next).to.equal(LIST_END) + expect((await shoyuBashi.getAdapterLink(DOMAIN_ID, ADDRESS_THREE)).previous).to.equal(ADDRESS_TWO) }) it("Emits AdaptersEnabled() event", async function () { const { shoyuBashi } = await setup() diff --git a/packages/evm/test/03_GiriGiriBashi.spec.ts b/packages/evm/test/03_GiriGiriBashi.spec.ts index c053aa5f..df378b2c 100644 --- a/packages/evm/test/03_GiriGiriBashi.spec.ts +++ b/packages/evm/test/03_GiriGiriBashi.spec.ts @@ -147,7 +147,7 @@ describe("GiriGiriBashi", function () { [settings, settings], ) await giriGiriBashi.setThreshold(DOMAIN_ID, 2) - expect((await giriGiriBashi.domains(DOMAIN_ID)).threshold).to.equal(2) + expect((await giriGiriBashi.getDomain(DOMAIN_ID)).threshold).to.equal(2) }) it("Emits HashiSet() event", async function () { const { giriGiriBashi, mockAdapter, secondMockAdapter, settings } = await setup() @@ -192,19 +192,19 @@ describe("GiriGiriBashi", function () { const adapters = await giriGiriBashi.getAdapters(DOMAIN_ID) await expect(adapters[0]).to.equal(ADDRESS_TWO) await expect(adapters[1]).to.equal(ADDRESS_THREE) - expect((await giriGiriBashi.adapters(DOMAIN_ID, LIST_END)).next).to.equal(ADDRESS_TWO) - expect((await giriGiriBashi.adapters(DOMAIN_ID, LIST_END)).previous).to.equal(ADDRESS_THREE) - expect((await giriGiriBashi.adapters(DOMAIN_ID, ADDRESS_TWO)).next).to.equal(ADDRESS_THREE) - expect((await giriGiriBashi.adapters(DOMAIN_ID, ADDRESS_TWO)).previous).to.equal(LIST_END) - expect((await giriGiriBashi.adapters(DOMAIN_ID, ADDRESS_THREE)).next).to.equal(LIST_END) - expect((await giriGiriBashi.adapters(DOMAIN_ID, ADDRESS_THREE)).previous).to.equal(ADDRESS_TWO) - let adapterSettings = await giriGiriBashi.settings(DOMAIN_ID, ADDRESS_TWO) + expect((await giriGiriBashi.getAdapterLink(DOMAIN_ID, LIST_END)).next).to.equal(ADDRESS_TWO) + expect((await giriGiriBashi.getAdapterLink(DOMAIN_ID, LIST_END)).previous).to.equal(ADDRESS_THREE) + expect((await giriGiriBashi.getAdapterLink(DOMAIN_ID, ADDRESS_TWO)).next).to.equal(ADDRESS_THREE) + expect((await giriGiriBashi.getAdapterLink(DOMAIN_ID, ADDRESS_TWO)).previous).to.equal(LIST_END) + expect((await giriGiriBashi.getAdapterLink(DOMAIN_ID, ADDRESS_THREE)).next).to.equal(LIST_END) + expect((await giriGiriBashi.getAdapterLink(DOMAIN_ID, ADDRESS_THREE)).previous).to.equal(ADDRESS_TWO) + let adapterSettings = await giriGiriBashi.getSettings(DOMAIN_ID, ADDRESS_TWO) expect(adapterSettings.quarantined).to.deep.equal(settings.quarantined) expect(adapterSettings.minimumBond).to.deep.equal(settings.minimumBond) expect(adapterSettings.startId).to.deep.equal(settings.startId) expect(adapterSettings.idDepth).to.deep.equal(settings.idDepth) expect(adapterSettings.timeout).to.deep.equal(settings.timeout) - adapterSettings = await giriGiriBashi.settings(DOMAIN_ID, ADDRESS_THREE) + adapterSettings = await giriGiriBashi.getSettings(DOMAIN_ID, ADDRESS_THREE) expect(adapterSettings.quarantined).to.deep.equal(settings.quarantined) expect(adapterSettings.minimumBond).to.deep.equal(settings.minimumBond) expect(adapterSettings.startId).to.deep.equal(settings.startId) @@ -245,10 +245,9 @@ describe("GiriGiriBashi", function () { [mockAdapter.address, secondMockAdapter.address], [settings, settings], ) - await giriGiriBashi.setThreshold(DOMAIN_ID, 2) - const oldHead = await giriGiriBashi.heads(DOMAIN_ID) + const oldHead = await giriGiriBashi.getHead(DOMAIN_ID) await giriGiriBashi.getUnanimousHash(DOMAIN_ID, 1) - const newHead = await giriGiriBashi.heads(DOMAIN_ID) + const newHead = await giriGiriBashi.getHead(DOMAIN_ID) expect(newHead).not.to.equal(oldHead) }) }) @@ -262,11 +261,10 @@ describe("GiriGiriBashi", function () { [mockAdapter.address, secondMockAdapter.address, thirdMockAdapter.address], [settings, settings, settings], ) - await giriGiriBashi.setThreshold(DOMAIN_ID, threshold) - const oldHead = await giriGiriBashi.heads(DOMAIN_ID) + const oldHead = await giriGiriBashi.getHead(DOMAIN_ID) expect(await giriGiriBashi.callStatic.getThresholdHash(DOMAIN_ID, 1)).to.equal(HASH_GOOD) await giriGiriBashi.getThresholdHash(DOMAIN_ID, 1) - const newHead = await giriGiriBashi.heads(DOMAIN_ID) + const newHead = await giriGiriBashi.getHead(DOMAIN_ID) expect(newHead).not.to.equal(oldHead) }) } @@ -287,9 +285,9 @@ describe("GiriGiriBashi", function () { } else { adapters = [secondMockAdapter.address, mockAdapter.address] } - const oldHead = await giriGiriBashi.heads(DOMAIN_ID) + const oldHead = await giriGiriBashi.getHead(DOMAIN_ID) await giriGiriBashi.getHash(DOMAIN_ID, 1, adapters) - const newHead = await giriGiriBashi.heads(DOMAIN_ID) + const newHead = await giriGiriBashi.getHead(DOMAIN_ID) expect(newHead).not.to.equal(oldHead) }) }) @@ -320,13 +318,13 @@ describe("GiriGiriBashi", function () { await giriGiriBashi.setThreshold(DOMAIN_ID, 2) await giriGiriBashi.getHash(DOMAIN_ID, 21, adapters) - const head = await giriGiriBashi.heads(DOMAIN_ID) + const head = await giriGiriBashi.getHead(DOMAIN_ID) const challengeBlock = head - CHALLENGE_RANGE + 2 await giriGiriBashi.challengeAdapter(DOMAIN_ID, challengeBlock, mockAdapter.address, { value: BOND, }) const challengeId = await giriGiriBashi.getChallengeId(DOMAIN_ID, challengeBlock, mockAdapter.address) - const challenge = await giriGiriBashi.challenges(challengeId) + const challenge = await giriGiriBashi.getChallenge(challengeId) const increaseAmount = challenge.timestamp.add(settings.timeout).add(1) await network.provider.send("evm_setNextBlockTimestamp", [increaseAmount.toHexString()]) @@ -347,13 +345,13 @@ describe("GiriGiriBashi", function () { await giriGiriBashi.setThreshold(DOMAIN_ID, 2) await giriGiriBashi.getHash(DOMAIN_ID, 21, adapters) - const head = await giriGiriBashi.heads(DOMAIN_ID) + const head = await giriGiriBashi.getHead(DOMAIN_ID) const challengeBlock = head - CHALLENGE_RANGE + 2 await giriGiriBashi.challengeAdapter(DOMAIN_ID, challengeBlock, mockAdapter.address, { value: BOND, }) const challengeId = await giriGiriBashi.getChallengeId(DOMAIN_ID, challengeBlock, mockAdapter.address) - const challenge = await giriGiriBashi.challenges(challengeId) + const challenge = await giriGiriBashi.getChallenge(challengeId) const increaseAmount = challenge.timestamp.add(settings.timeout).add(1) await network.provider.send("evm_setNextBlockTimestamp", [increaseAmount.toHexString()]) @@ -373,7 +371,7 @@ describe("GiriGiriBashi", function () { await giriGiriBashi.enableAdapters(DOMAIN_ID, adapters, [settings, settings]) await giriGiriBashi.getHash(DOMAIN_ID, 21, adapters) - const head = await giriGiriBashi.heads(DOMAIN_ID) + const head = await giriGiriBashi.getHead(DOMAIN_ID) const challengeBlock = head - CHALLENGE_RANGE + 2 await giriGiriBashi.challengeAdapter(DOMAIN_ID, challengeBlock, mockAdapter.address, { value: BOND, @@ -390,7 +388,7 @@ describe("GiriGiriBashi", function () { await giriGiriBashi.enableAdapters(DOMAIN_ID, adapters, [settings, settings]) await giriGiriBashi.setThreshold(DOMAIN_ID, 2) await giriGiriBashi.getHash(DOMAIN_ID, 21, adapters) - const head = await giriGiriBashi.heads(DOMAIN_ID) + const head = await giriGiriBashi.getHead(DOMAIN_ID) expect( await giriGiriBashi.challengeAdapter(DOMAIN_ID, head - CHALLENGE_RANGE + 1, mockAdapter.address, { value: BOND, @@ -408,7 +406,7 @@ describe("GiriGiriBashi", function () { await giriGiriBashi.enableAdapters(DOMAIN_ID, adapters, [settings, settings]) await giriGiriBashi.setThreshold(DOMAIN_ID, 2) await giriGiriBashi.getHash(DOMAIN_ID, 21, adapters) - const head = await giriGiriBashi.heads(DOMAIN_ID) + const head = await giriGiriBashi.getHead(DOMAIN_ID) // revert on block before start ID await expect(giriGiriBashi.callStatic.challengeAdapter(DOMAIN_ID, 0, mockAdapter.address, { value: BOND })) @@ -449,7 +447,7 @@ describe("GiriGiriBashi", function () { await giriGiriBashi.setThreshold(DOMAIN_ID, 2) await giriGiriBashi.getHash(DOMAIN_ID, 21, adapters) - const head = await giriGiriBashi.heads(DOMAIN_ID) + const head = await giriGiriBashi.getHead(DOMAIN_ID) expect( await giriGiriBashi.challengeAdapter(DOMAIN_ID, head - CHALLENGE_RANGE + 1, mockAdapter.address, { value: BOND, @@ -462,7 +460,7 @@ describe("GiriGiriBashi", function () { await giriGiriBashi.enableAdapters(DOMAIN_ID, adapters, [settings, settings]) await giriGiriBashi.setThreshold(DOMAIN_ID, 2) await giriGiriBashi.getHash(DOMAIN_ID, 21, adapters) - const head = await giriGiriBashi.heads(DOMAIN_ID) + const head = await giriGiriBashi.getHead(DOMAIN_ID) await expect( giriGiriBashi.challengeAdapter(DOMAIN_ID, head - CHALLENGE_RANGE + 1, mockAdapter.address, { @@ -486,13 +484,13 @@ describe("GiriGiriBashi", function () { await giriGiriBashi.setThreshold(DOMAIN_ID, 2) await giriGiriBashi.getHash(DOMAIN_ID, 21, adapters) - const head = await giriGiriBashi.heads(DOMAIN_ID) + const head = await giriGiriBashi.getHead(DOMAIN_ID) const challengeBlock = head - CHALLENGE_RANGE + 1 await giriGiriBashi.challengeAdapter(DOMAIN_ID, challengeBlock, mockAdapter.address, { value: BOND, }) const challengeId = await giriGiriBashi.getChallengeId(DOMAIN_ID, challengeBlock, mockAdapter.address) - const challenge = await giriGiriBashi.challenges(challengeId) + const challenge = await giriGiriBashi.getChallenge(challengeId) const increaseAmount = challenge.timestamp.add(settings.timeout).sub(1) await network.provider.send("evm_setNextBlockTimestamp", [increaseAmount.toHexString()]) @@ -507,14 +505,14 @@ describe("GiriGiriBashi", function () { await giriGiriBashi.enableAdapters(DOMAIN_ID, adapters, [settings, settings]) await giriGiriBashi.setThreshold(DOMAIN_ID, 2) await giriGiriBashi.getHash(DOMAIN_ID, 21, adapters) - const head = await giriGiriBashi.heads(DOMAIN_ID) + const head = await giriGiriBashi.getHead(DOMAIN_ID) const challengeBlock = head - CHALLENGE_RANGE + 1 await giriGiriBashi.challengeAdapter(DOMAIN_ID, challengeBlock, mockAdapter.address, { value: BOND, }) const challengeId = await giriGiriBashi.getChallengeId(DOMAIN_ID, challengeBlock, mockAdapter.address) - const challenge = await giriGiriBashi.challenges(challengeId) + const challenge = await giriGiriBashi.getChallenge(challengeId) const increaseAmount = challenge.timestamp.add(settings.timeout).add(1) await network.provider.send("evm_setNextBlockTimestamp", [increaseAmount.toHexString()]) @@ -526,7 +524,7 @@ describe("GiriGiriBashi", function () { const newBalance = await ethers.provider.getBalance(wallet.address) await expect(newBalance).to.be.greaterThan(previousBalance) - const quarantined = (await giriGiriBashi.settings(DOMAIN_ID, mockAdapter.address)).quarantined + const quarantined = (await giriGiriBashi.getSettings(DOMAIN_ID, mockAdapter.address)).quarantined await expect(quarantined).to.equal(true) }) it("Keeps bond if _adapters + adapter equals threshold and agree", async function () { @@ -536,7 +534,7 @@ describe("GiriGiriBashi", function () { await giriGiriBashi.setThreshold(DOMAIN_ID, 2) await giriGiriBashi.getHash(DOMAIN_ID, 1, adapters) - const head = await giriGiriBashi.heads(DOMAIN_ID) + const head = await giriGiriBashi.getHead(DOMAIN_ID) const challengeBlock = head.add(20) await giriGiriBashi.challengeAdapter(DOMAIN_ID, challengeBlock, mockAdapter.address, { value: BOND, @@ -545,7 +543,7 @@ describe("GiriGiriBashi", function () { const balanceBefore = await ethers.provider.getBalance(ADDRESS_TWO) await giriGiriBashi.resolveChallenge(DOMAIN_ID, challengeBlock, mockAdapter.address, [secondMockAdapter.address]) expect(await ethers.provider.getBalance(ADDRESS_TWO)).to.equal(balanceBefore.add(BOND)) - const quarantined = (await giriGiriBashi.settings(DOMAIN_ID, mockAdapter.address)).quarantined + const quarantined = (await giriGiriBashi.getSettings(DOMAIN_ID, mockAdapter.address)).quarantined expect(quarantined).to.equal(false) }) it("Reverts if _adapters + adapter equals threshold and disagree", async function () { @@ -555,7 +553,7 @@ describe("GiriGiriBashi", function () { await giriGiriBashi.setThreshold(DOMAIN_ID, 2) await giriGiriBashi.getHash(DOMAIN_ID, 21, adapters) - const head = await giriGiriBashi.heads(DOMAIN_ID) + const head = await giriGiriBashi.getHead(DOMAIN_ID) const challengeBlock = head.add(1) await giriGiriBashi.challengeAdapter(DOMAIN_ID, challengeBlock, mockAdapter.address, { value: BOND, @@ -575,7 +573,7 @@ describe("GiriGiriBashi", function () { adapters = adapters.sort(compareAddresses) await giriGiriBashi.getHash(DOMAIN_ID, 1, adapters) - const head = await giriGiriBashi.heads(DOMAIN_ID) + const head = await giriGiriBashi.getHead(DOMAIN_ID) const challengeBlock = head.add(20) await giriGiriBashi.challengeAdapter(DOMAIN_ID, challengeBlock, mockAdapter.address, { value: BOND, @@ -590,7 +588,7 @@ describe("GiriGiriBashi", function () { [secondMockAdapter.address, thirdMockAdapter.address].sort(compareAddresses), ) expect(await ethers.provider.getBalance(ADDRESS_TWO)).to.equal(previousBalance.add(BOND)) - const quarantined = (await giriGiriBashi.settings(DOMAIN_ID, mockAdapter.address)).quarantined + const quarantined = (await giriGiriBashi.getSettings(DOMAIN_ID, mockAdapter.address)).quarantined expect(quarantined).to.equal(false) }) it("Quarantines adapter and returns bond if challenged adapter disagrees with canonical hash", async function () { @@ -601,7 +599,7 @@ describe("GiriGiriBashi", function () { adapters = adapters.sort(compareAddresses) await giriGiriBashi.getHash(DOMAIN_ID, 21, adapters) - const head = await giriGiriBashi.heads(DOMAIN_ID) + const head = await giriGiriBashi.getHead(DOMAIN_ID) const challengeBlock = head.add(1) await giriGiriBashi.challengeAdapter(DOMAIN_ID, challengeBlock, mockAdapter.address, { value: BOND, @@ -613,7 +611,7 @@ describe("GiriGiriBashi", function () { mockAdapter.address, [secondMockAdapter.address, thirdMockAdapter.address].sort(compareAddresses), ) - const quarantined = (await giriGiriBashi.settings(DOMAIN_ID, mockAdapter.address)).quarantined + const quarantined = (await giriGiriBashi.getSettings(DOMAIN_ID, mockAdapter.address)).quarantined await expect(quarantined).to.equal(true) }) it("Clears state after challenge is resolved", async function () { @@ -624,7 +622,7 @@ describe("GiriGiriBashi", function () { adapters = adapters.sort(compareAddresses) await giriGiriBashi.getHash(DOMAIN_ID, 21, adapters) - const head = await giriGiriBashi.heads(DOMAIN_ID) + const head = await giriGiriBashi.getHead(DOMAIN_ID) const challengeBlock = head.add(1) await giriGiriBashi.challengeAdapter(DOMAIN_ID, challengeBlock, mockAdapter.address, { value: BOND, @@ -636,10 +634,10 @@ describe("GiriGiriBashi", function () { mockAdapter.address, [secondMockAdapter.address, thirdMockAdapter.address].sort(compareAddresses), ) - const quarantined = (await giriGiriBashi.settings(DOMAIN_ID, mockAdapter.address)).quarantined + const quarantined = (await giriGiriBashi.getSettings(DOMAIN_ID, mockAdapter.address)).quarantined expect(quarantined).to.equal(true) const challengeId = await giriGiriBashi.getChallengeId(DOMAIN_ID, challengeBlock, mockAdapter.address) - const challenge = await giriGiriBashi.challenges(challengeId) + const challenge = await giriGiriBashi.getChallenge(challengeId) expect(challenge.challenger).to.equal(ADDRESS_ZERO) expect(challenge.timestamp).to.equal(0) expect(challenge.bond).to.equal(0) @@ -651,7 +649,7 @@ describe("GiriGiriBashi", function () { await giriGiriBashi.setThreshold(DOMAIN_ID, 2) await giriGiriBashi.getHash(DOMAIN_ID, 21, adapters) - const head = await giriGiriBashi.heads(DOMAIN_ID) + const head = await giriGiriBashi.getHead(DOMAIN_ID) const challengeBlock = head.add(1) await giriGiriBashi.challengeAdapter(DOMAIN_ID, challengeBlock, mockAdapter.address, { value: BOND, @@ -706,8 +704,8 @@ describe("GiriGiriBashi", function () { await giriGiriBashi.enableAdapters(DOMAIN_ID, adapters, [settings, settings, settings]) await giriGiriBashi.setThreshold(DOMAIN_ID, 2) expect(await giriGiriBashi.declareNoConfidence(DOMAIN_ID, 20, adapters)) - const domain = await giriGiriBashi.domains(DOMAIN_ID) - const challengeRange = await giriGiriBashi.challengeRanges(DOMAIN_ID) + const domain = await giriGiriBashi.getDomain(DOMAIN_ID) + const challengeRange = await giriGiriBashi.getChallengeRange(DOMAIN_ID) expect(domain.threshold).to.equal(ethers.constants.MaxUint256) expect(challengeRange).to.equal(0) }) @@ -743,7 +741,7 @@ describe("GiriGiriBashi", function () { it("Sets challenge range for given domain", async function () { const { giriGiriBashi } = await setup() expect(await giriGiriBashi.setChallengeRange(2, CHALLENGE_RANGE)) - const challengeRange = await giriGiriBashi.challengeRanges(2) + const challengeRange = await giriGiriBashi.getChallengeRange(2) expect(challengeRange).to.equal(CHALLENGE_RANGE) }) it("Emits the ChallengeRangeUpdated event", async function () { @@ -813,7 +811,7 @@ describe("GiriGiriBashi", function () { adapters = adapters.sort(compareAddresses) await giriGiriBashi.getHash(DOMAIN_ID, 21, adapters) - const head = await giriGiriBashi.heads(DOMAIN_ID) + const head = await giriGiriBashi.getHead(DOMAIN_ID) const challengeBlock = head.add(1) await giriGiriBashi.challengeAdapter(DOMAIN_ID, challengeBlock, mockAdapter.address, { value: BOND, @@ -828,7 +826,7 @@ describe("GiriGiriBashi", function () { expect( await giriGiriBashi.replaceQuarantinedAdapters(DOMAIN_ID, [mockAdapter.address], [ADDRESS_TWO], [settings]), ) - const adapterSettings = await giriGiriBashi.settings(DOMAIN_ID, ADDRESS_TWO) + const adapterSettings = await giriGiriBashi.getSettings(DOMAIN_ID, ADDRESS_TWO) expect(adapterSettings.quarantined).to.deep.equal(settings.quarantined) expect(adapterSettings.minimumBond).to.deep.equal(settings.minimumBond) expect(adapterSettings.startId).to.deep.equal(settings.startId)