diff --git a/.circleci/config.yml b/.circleci/config.yml
index dfa6dc0a5e..e1362db265 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -61,6 +61,10 @@ step_compile_mock_spy: &step_compile_mock_spy
cd ./../.. && npx hardhat compile
cp ./packages/wormhole-relayer/config.example.js ./packages/wormhole-relayer/config.js
npx tsc
+step_generate_wormhole_types: &step_generate_wormhole_types
+ run:
+ name: "Generate wormhole API types for mock endpoint"
+ command: sudo apt install default-jre && cd ./helpers/wormholescanMock && pnpm i && npm run generate-types
jobs:
build-checks:
@@ -83,10 +87,10 @@ jobs:
- run:
name: "Checking contract storage layout hasn't had additions made"
command: rm -rf .storage-layouts-normalized && npx hardhat storage-layout --update && npm run normalize:storageSlots && test -z "$(git status --porcelain)"
- - <<: *step_compile_mock_spy
- run:
name: "Linting JavaScript"
command: pnpm run eslint
+ - <<: *step_compile_mock_spy
- run:
name: "Linting Solidity"
command: pnpm run solhint
@@ -319,6 +323,11 @@ jobs:
command: CHAIN_ID=100 pnpm run test:contracts:chainid:coverage
environment:
NODE_OPTIONS: --max-old-space-size=6144
+ - run:
+ name: "Running chainid tests for Arbitrum One"
+ command: CHAIN_ID=42161 pnpm run test:contracts:chainid:coverage
+ environment:
+ NODE_OPTIONS: --max-old-space-size=6144
- run:
name: "Running chainid tests with coverage for an unsupported network"
command: CHAIN_ID=777 pnpm run test:contracts:chainid:coverage
@@ -327,10 +336,10 @@ jobs:
- persist_to_workspace:
root: ./
paths:
- - coverage-chainid-1
- - coverage-chainid-5
- coverage-chainid-100
+ - coverage-chainid-42161
- coverage-chainid-777
+ - coverage-chainid-1
coverage-test-bridging:
<<: *job_common
resource_class: large
@@ -343,6 +352,7 @@ jobs:
- <<: *step_setup_global_packages
- <<: *step_install_lsof
- <<: *step_compile_mock_spy
+ - <<: *step_generate_wormhole_types
- run:
name: "Installing the safe-contracts dependencies"
command: cd ./lib/safe-contracts && pnpm i --ignore-scripts
diff --git a/.eslintignore b/.eslintignore
index 959bc274cf..f24dd7f70b 100644
--- a/.eslintignore
+++ b/.eslintignore
@@ -7,3 +7,4 @@ keys/*
lib/*
packages/**/node_modules
scripts/mockGuardianSpy.js
+helpers/wormholescanMock/dist/*
\ No newline at end of file
diff --git a/.eslintrc b/.eslintrc
index b687bdebe9..5d3bdb717d 100644
--- a/.eslintrc
+++ b/.eslintrc
@@ -43,6 +43,7 @@
"error",
"ignorePackages",
{
+ "": "never",
"js": "never",
"jsx": "never",
"ts": "never",
diff --git a/.gitignore b/.gitignore
index 8c1a8e6670..f27d1e47e6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -37,3 +37,4 @@ coverage-extensions/
.pnpm-store
.storage-layouts
scripts/mockGuardianSpy.js
+helpers/wormholescanMock/src/encodeMockVAA.js
\ No newline at end of file
diff --git a/.soliumrc.json b/.soliumrc.json
index 450acbc769..712f0e541b 100644
--- a/.soliumrc.json
+++ b/.soliumrc.json
@@ -12,6 +12,7 @@
"error-reason": "error",
"max-len": "error",
"no-trailing-whitespace": "error",
- "blank-lines": "error"
+ "blank-lines": "error",
+ "custom-errors": "off"
}
}
diff --git a/.storage-layouts-normalized/contracts/bridging/ProxyColony.sol:ProxyColony.json b/.storage-layouts-normalized/contracts/bridging/ProxyColony.sol:ProxyColony.json
new file mode 100644
index 0000000000..f020621b32
--- /dev/null
+++ b/.storage-layouts-normalized/contracts/bridging/ProxyColony.sol:ProxyColony.json
@@ -0,0 +1,79 @@
+{
+ "storage": [
+ {
+ "contract": "contracts/bridging/ProxyColony.sol:ProxyColony",
+ "label": "authority",
+ "offset": 0,
+ "slot": "0",
+ "type": {
+ "encoding": "inplace",
+ "label": "contract DSAuthority",
+ "numberOfBytes": "20"
+ }
+ },
+ {
+ "contract": "contracts/bridging/ProxyColony.sol:ProxyColony",
+ "label": "owner",
+ "offset": 0,
+ "slot": "1",
+ "type": {
+ "encoding": "inplace",
+ "label": "address",
+ "numberOfBytes": "20"
+ }
+ },
+ {
+ "contract": "contracts/bridging/ProxyColony.sol:ProxyColony",
+ "label": "resolver",
+ "offset": 0,
+ "slot": "2",
+ "type": {
+ "encoding": "inplace",
+ "label": "address",
+ "numberOfBytes": "20"
+ }
+ },
+ {
+ "contract": "contracts/bridging/ProxyColony.sol:ProxyColony",
+ "label": "metatransactionNonces",
+ "offset": 0,
+ "slot": "3",
+ "type": {
+ "encoding": "mapping",
+ "key": {
+ "encoding": "inplace",
+ "label": "address",
+ "numberOfBytes": "20"
+ },
+ "label": "mapping(address => uint256)",
+ "numberOfBytes": "32",
+ "value": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ }
+ }
+ },
+ {
+ "contract": "contracts/bridging/ProxyColony.sol:ProxyColony",
+ "label": "tokenBalances",
+ "offset": 0,
+ "slot": "4",
+ "type": {
+ "encoding": "mapping",
+ "key": {
+ "encoding": "inplace",
+ "label": "address",
+ "numberOfBytes": "20"
+ },
+ "label": "mapping(address => uint256)",
+ "numberOfBytes": "32",
+ "value": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ }
+ }
+ }
+ ]
+}
\ No newline at end of file
diff --git a/.storage-layouts-normalized/contracts/bridging/ProxyColonyNetwork.sol:ProxyColonyNetwork.json b/.storage-layouts-normalized/contracts/bridging/ProxyColonyNetwork.sol:ProxyColonyNetwork.json
new file mode 100644
index 0000000000..eacdeddbc0
--- /dev/null
+++ b/.storage-layouts-normalized/contracts/bridging/ProxyColonyNetwork.sol:ProxyColonyNetwork.json
@@ -0,0 +1,102 @@
+{
+ "storage": [
+ {
+ "contract": "contracts/bridging/ProxyColonyNetwork.sol:ProxyColonyNetwork",
+ "label": "authority",
+ "offset": 0,
+ "slot": "0",
+ "type": {
+ "encoding": "inplace",
+ "label": "contract DSAuthority",
+ "numberOfBytes": "20"
+ }
+ },
+ {
+ "contract": "contracts/bridging/ProxyColonyNetwork.sol:ProxyColonyNetwork",
+ "label": "owner",
+ "offset": 0,
+ "slot": "1",
+ "type": {
+ "encoding": "inplace",
+ "label": "address",
+ "numberOfBytes": "20"
+ }
+ },
+ {
+ "contract": "contracts/bridging/ProxyColonyNetwork.sol:ProxyColonyNetwork",
+ "label": "resolver",
+ "offset": 0,
+ "slot": "2",
+ "type": {
+ "encoding": "inplace",
+ "label": "address",
+ "numberOfBytes": "20"
+ }
+ },
+ {
+ "contract": "contracts/bridging/ProxyColonyNetwork.sol:ProxyColonyNetwork",
+ "label": "colonyBridgeAddress",
+ "offset": 0,
+ "slot": "3",
+ "type": {
+ "encoding": "inplace",
+ "label": "address",
+ "numberOfBytes": "20"
+ }
+ },
+ {
+ "contract": "contracts/bridging/ProxyColonyNetwork.sol:ProxyColonyNetwork",
+ "label": "homeChainId",
+ "offset": 0,
+ "slot": "4",
+ "type": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ }
+ },
+ {
+ "contract": "contracts/bridging/ProxyColonyNetwork.sol:ProxyColonyNetwork",
+ "label": "proxyColonyResolverAddress",
+ "offset": 0,
+ "slot": "5",
+ "type": {
+ "encoding": "inplace",
+ "label": "address",
+ "numberOfBytes": "20"
+ }
+ },
+ {
+ "contract": "contracts/bridging/ProxyColonyNetwork.sol:ProxyColonyNetwork",
+ "label": "proxyColonies",
+ "offset": 0,
+ "slot": "6",
+ "type": {
+ "encoding": "mapping",
+ "key": {
+ "encoding": "inplace",
+ "label": "address",
+ "numberOfBytes": "20"
+ },
+ "label": "mapping(address => bool)",
+ "numberOfBytes": "32",
+ "value": {
+ "encoding": "inplace",
+ "label": "bool",
+ "numberOfBytes": "1"
+ }
+ }
+ },
+ {
+ "contract": "contracts/bridging/ProxyColonyNetwork.sol:ProxyColonyNetwork",
+ "label": "domainTokenReceiverResolver",
+ "offset": 0,
+ "slot": "7",
+ "type": {
+ "encoding": "inplace",
+ "label": "address",
+ "numberOfBytes": "20"
+ }
+ }
+ ]
+}
\ No newline at end of file
diff --git a/.storage-layouts-normalized/contracts/colony/Colony.sol:Colony.json b/.storage-layouts-normalized/contracts/colony/Colony.sol:Colony.json
index bdaaa40296..908d8f0c2d 100644
--- a/.storage-layouts-normalized/contracts/colony/Colony.sol:Colony.json
+++ b/.storage-layouts-normalized/contracts/colony/Colony.sol:Colony.json
@@ -506,9 +506,71 @@
"label": "uint256",
"numberOfBytes": "32"
}
+ },
+ {
+ "contract": "contracts/colony/Colony.sol:Colony",
+ "label": "chainBalances",
+ "offset": 0,
+ "slot": "5",
+ "type": {
+ "encoding": "mapping",
+ "key": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ },
+ "label": "mapping(uint256 => mapping(address => uint256))",
+ "numberOfBytes": "32",
+ "value": {
+ "encoding": "mapping",
+ "key": {
+ "encoding": "inplace",
+ "label": "address",
+ "numberOfBytes": "20"
+ },
+ "label": "mapping(address => uint256)",
+ "numberOfBytes": "32",
+ "value": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ }
+ }
+ }
+ },
+ {
+ "contract": "contracts/colony/Colony.sol:Colony",
+ "label": "chainPayouts",
+ "offset": 0,
+ "slot": "6",
+ "type": {
+ "encoding": "mapping",
+ "key": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ },
+ "label": "mapping(uint256 => mapping(address => uint256))",
+ "numberOfBytes": "32",
+ "value": {
+ "encoding": "mapping",
+ "key": {
+ "encoding": "inplace",
+ "label": "address",
+ "numberOfBytes": "20"
+ },
+ "label": "mapping(address => uint256)",
+ "numberOfBytes": "32",
+ "value": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ }
+ }
+ }
}
],
- "numberOfBytes": "160"
+ "numberOfBytes": "224"
}
}
},
@@ -1430,6 +1492,88 @@
"numberOfBytes": "32"
}
}
+ },
+ {
+ "contract": "contracts/colony/Colony.sol:Colony",
+ "label": "expenditureSlotChainPayouts",
+ "offset": 0,
+ "slot": "40",
+ "type": {
+ "encoding": "mapping",
+ "key": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ },
+ "label": "mapping(uint256 => mapping(uint256 => mapping(uint256 => mapping(address => uint256))))",
+ "numberOfBytes": "32",
+ "value": {
+ "encoding": "mapping",
+ "key": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ },
+ "label": "mapping(uint256 => mapping(uint256 => mapping(address => uint256)))",
+ "numberOfBytes": "32",
+ "value": {
+ "encoding": "mapping",
+ "key": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ },
+ "label": "mapping(uint256 => mapping(address => uint256))",
+ "numberOfBytes": "32",
+ "value": {
+ "encoding": "mapping",
+ "key": {
+ "encoding": "inplace",
+ "label": "address",
+ "numberOfBytes": "20"
+ },
+ "label": "mapping(address => uint256)",
+ "numberOfBytes": "32",
+ "value": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ }
+ }
+ }
+ }
+ }
+ },
+ {
+ "contract": "contracts/colony/Colony.sol:Colony",
+ "label": "chainNonRewardPotsTotals",
+ "offset": 0,
+ "slot": "41",
+ "type": {
+ "encoding": "mapping",
+ "key": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ },
+ "label": "mapping(uint256 => mapping(address => uint256))",
+ "numberOfBytes": "32",
+ "value": {
+ "encoding": "mapping",
+ "key": {
+ "encoding": "inplace",
+ "label": "address",
+ "numberOfBytes": "20"
+ },
+ "label": "mapping(address => uint256)",
+ "numberOfBytes": "32",
+ "value": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ }
+ }
+ }
}
]
}
\ No newline at end of file
diff --git a/.storage-layouts-normalized/contracts/colony/ColonyArbitraryTransaction.sol:ColonyArbitraryTransaction.json b/.storage-layouts-normalized/contracts/colony/ColonyArbitraryTransaction.sol:ColonyArbitraryTransaction.json
index 44da3bf9d0..ae97490c36 100644
--- a/.storage-layouts-normalized/contracts/colony/ColonyArbitraryTransaction.sol:ColonyArbitraryTransaction.json
+++ b/.storage-layouts-normalized/contracts/colony/ColonyArbitraryTransaction.sol:ColonyArbitraryTransaction.json
@@ -506,9 +506,71 @@
"label": "uint256",
"numberOfBytes": "32"
}
+ },
+ {
+ "contract": "contracts/colony/ColonyArbitraryTransaction.sol:ColonyArbitraryTransaction",
+ "label": "chainBalances",
+ "offset": 0,
+ "slot": "5",
+ "type": {
+ "encoding": "mapping",
+ "key": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ },
+ "label": "mapping(uint256 => mapping(address => uint256))",
+ "numberOfBytes": "32",
+ "value": {
+ "encoding": "mapping",
+ "key": {
+ "encoding": "inplace",
+ "label": "address",
+ "numberOfBytes": "20"
+ },
+ "label": "mapping(address => uint256)",
+ "numberOfBytes": "32",
+ "value": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ }
+ }
+ }
+ },
+ {
+ "contract": "contracts/colony/ColonyArbitraryTransaction.sol:ColonyArbitraryTransaction",
+ "label": "chainPayouts",
+ "offset": 0,
+ "slot": "6",
+ "type": {
+ "encoding": "mapping",
+ "key": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ },
+ "label": "mapping(uint256 => mapping(address => uint256))",
+ "numberOfBytes": "32",
+ "value": {
+ "encoding": "mapping",
+ "key": {
+ "encoding": "inplace",
+ "label": "address",
+ "numberOfBytes": "20"
+ },
+ "label": "mapping(address => uint256)",
+ "numberOfBytes": "32",
+ "value": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ }
+ }
+ }
}
],
- "numberOfBytes": "160"
+ "numberOfBytes": "224"
}
}
},
@@ -1430,6 +1492,88 @@
"numberOfBytes": "32"
}
}
+ },
+ {
+ "contract": "contracts/colony/ColonyArbitraryTransaction.sol:ColonyArbitraryTransaction",
+ "label": "expenditureSlotChainPayouts",
+ "offset": 0,
+ "slot": "40",
+ "type": {
+ "encoding": "mapping",
+ "key": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ },
+ "label": "mapping(uint256 => mapping(uint256 => mapping(uint256 => mapping(address => uint256))))",
+ "numberOfBytes": "32",
+ "value": {
+ "encoding": "mapping",
+ "key": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ },
+ "label": "mapping(uint256 => mapping(uint256 => mapping(address => uint256)))",
+ "numberOfBytes": "32",
+ "value": {
+ "encoding": "mapping",
+ "key": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ },
+ "label": "mapping(uint256 => mapping(address => uint256))",
+ "numberOfBytes": "32",
+ "value": {
+ "encoding": "mapping",
+ "key": {
+ "encoding": "inplace",
+ "label": "address",
+ "numberOfBytes": "20"
+ },
+ "label": "mapping(address => uint256)",
+ "numberOfBytes": "32",
+ "value": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ }
+ }
+ }
+ }
+ }
+ },
+ {
+ "contract": "contracts/colony/ColonyArbitraryTransaction.sol:ColonyArbitraryTransaction",
+ "label": "chainNonRewardPotsTotals",
+ "offset": 0,
+ "slot": "41",
+ "type": {
+ "encoding": "mapping",
+ "key": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ },
+ "label": "mapping(uint256 => mapping(address => uint256))",
+ "numberOfBytes": "32",
+ "value": {
+ "encoding": "mapping",
+ "key": {
+ "encoding": "inplace",
+ "label": "address",
+ "numberOfBytes": "20"
+ },
+ "label": "mapping(address => uint256)",
+ "numberOfBytes": "32",
+ "value": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ }
+ }
+ }
}
]
}
\ No newline at end of file
diff --git a/.storage-layouts-normalized/contracts/colony/ColonyDomains.sol:ColonyDomains.json b/.storage-layouts-normalized/contracts/colony/ColonyDomains.sol:ColonyDomains.json
index b35aaabbd4..2e9c3eab58 100644
--- a/.storage-layouts-normalized/contracts/colony/ColonyDomains.sol:ColonyDomains.json
+++ b/.storage-layouts-normalized/contracts/colony/ColonyDomains.sol:ColonyDomains.json
@@ -506,9 +506,71 @@
"label": "uint256",
"numberOfBytes": "32"
}
+ },
+ {
+ "contract": "contracts/colony/ColonyDomains.sol:ColonyDomains",
+ "label": "chainBalances",
+ "offset": 0,
+ "slot": "5",
+ "type": {
+ "encoding": "mapping",
+ "key": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ },
+ "label": "mapping(uint256 => mapping(address => uint256))",
+ "numberOfBytes": "32",
+ "value": {
+ "encoding": "mapping",
+ "key": {
+ "encoding": "inplace",
+ "label": "address",
+ "numberOfBytes": "20"
+ },
+ "label": "mapping(address => uint256)",
+ "numberOfBytes": "32",
+ "value": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ }
+ }
+ }
+ },
+ {
+ "contract": "contracts/colony/ColonyDomains.sol:ColonyDomains",
+ "label": "chainPayouts",
+ "offset": 0,
+ "slot": "6",
+ "type": {
+ "encoding": "mapping",
+ "key": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ },
+ "label": "mapping(uint256 => mapping(address => uint256))",
+ "numberOfBytes": "32",
+ "value": {
+ "encoding": "mapping",
+ "key": {
+ "encoding": "inplace",
+ "label": "address",
+ "numberOfBytes": "20"
+ },
+ "label": "mapping(address => uint256)",
+ "numberOfBytes": "32",
+ "value": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ }
+ }
+ }
}
],
- "numberOfBytes": "160"
+ "numberOfBytes": "224"
}
}
},
@@ -1430,6 +1492,88 @@
"numberOfBytes": "32"
}
}
+ },
+ {
+ "contract": "contracts/colony/ColonyDomains.sol:ColonyDomains",
+ "label": "expenditureSlotChainPayouts",
+ "offset": 0,
+ "slot": "40",
+ "type": {
+ "encoding": "mapping",
+ "key": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ },
+ "label": "mapping(uint256 => mapping(uint256 => mapping(uint256 => mapping(address => uint256))))",
+ "numberOfBytes": "32",
+ "value": {
+ "encoding": "mapping",
+ "key": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ },
+ "label": "mapping(uint256 => mapping(uint256 => mapping(address => uint256)))",
+ "numberOfBytes": "32",
+ "value": {
+ "encoding": "mapping",
+ "key": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ },
+ "label": "mapping(uint256 => mapping(address => uint256))",
+ "numberOfBytes": "32",
+ "value": {
+ "encoding": "mapping",
+ "key": {
+ "encoding": "inplace",
+ "label": "address",
+ "numberOfBytes": "20"
+ },
+ "label": "mapping(address => uint256)",
+ "numberOfBytes": "32",
+ "value": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ }
+ }
+ }
+ }
+ }
+ },
+ {
+ "contract": "contracts/colony/ColonyDomains.sol:ColonyDomains",
+ "label": "chainNonRewardPotsTotals",
+ "offset": 0,
+ "slot": "41",
+ "type": {
+ "encoding": "mapping",
+ "key": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ },
+ "label": "mapping(uint256 => mapping(address => uint256))",
+ "numberOfBytes": "32",
+ "value": {
+ "encoding": "mapping",
+ "key": {
+ "encoding": "inplace",
+ "label": "address",
+ "numberOfBytes": "20"
+ },
+ "label": "mapping(address => uint256)",
+ "numberOfBytes": "32",
+ "value": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ }
+ }
+ }
}
]
}
\ No newline at end of file
diff --git a/.storage-layouts-normalized/contracts/colony/ColonyExpenditure.sol:ColonyExpenditure.json b/.storage-layouts-normalized/contracts/colony/ColonyExpenditure.sol:ColonyExpenditure.json
index d24e1daa9f..cefb3cc1e8 100644
--- a/.storage-layouts-normalized/contracts/colony/ColonyExpenditure.sol:ColonyExpenditure.json
+++ b/.storage-layouts-normalized/contracts/colony/ColonyExpenditure.sol:ColonyExpenditure.json
@@ -506,9 +506,71 @@
"label": "uint256",
"numberOfBytes": "32"
}
+ },
+ {
+ "contract": "contracts/colony/ColonyExpenditure.sol:ColonyExpenditure",
+ "label": "chainBalances",
+ "offset": 0,
+ "slot": "5",
+ "type": {
+ "encoding": "mapping",
+ "key": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ },
+ "label": "mapping(uint256 => mapping(address => uint256))",
+ "numberOfBytes": "32",
+ "value": {
+ "encoding": "mapping",
+ "key": {
+ "encoding": "inplace",
+ "label": "address",
+ "numberOfBytes": "20"
+ },
+ "label": "mapping(address => uint256)",
+ "numberOfBytes": "32",
+ "value": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ }
+ }
+ }
+ },
+ {
+ "contract": "contracts/colony/ColonyExpenditure.sol:ColonyExpenditure",
+ "label": "chainPayouts",
+ "offset": 0,
+ "slot": "6",
+ "type": {
+ "encoding": "mapping",
+ "key": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ },
+ "label": "mapping(uint256 => mapping(address => uint256))",
+ "numberOfBytes": "32",
+ "value": {
+ "encoding": "mapping",
+ "key": {
+ "encoding": "inplace",
+ "label": "address",
+ "numberOfBytes": "20"
+ },
+ "label": "mapping(address => uint256)",
+ "numberOfBytes": "32",
+ "value": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ }
+ }
+ }
}
],
- "numberOfBytes": "160"
+ "numberOfBytes": "224"
}
}
},
@@ -1430,6 +1492,88 @@
"numberOfBytes": "32"
}
}
+ },
+ {
+ "contract": "contracts/colony/ColonyExpenditure.sol:ColonyExpenditure",
+ "label": "expenditureSlotChainPayouts",
+ "offset": 0,
+ "slot": "40",
+ "type": {
+ "encoding": "mapping",
+ "key": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ },
+ "label": "mapping(uint256 => mapping(uint256 => mapping(uint256 => mapping(address => uint256))))",
+ "numberOfBytes": "32",
+ "value": {
+ "encoding": "mapping",
+ "key": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ },
+ "label": "mapping(uint256 => mapping(uint256 => mapping(address => uint256)))",
+ "numberOfBytes": "32",
+ "value": {
+ "encoding": "mapping",
+ "key": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ },
+ "label": "mapping(uint256 => mapping(address => uint256))",
+ "numberOfBytes": "32",
+ "value": {
+ "encoding": "mapping",
+ "key": {
+ "encoding": "inplace",
+ "label": "address",
+ "numberOfBytes": "20"
+ },
+ "label": "mapping(address => uint256)",
+ "numberOfBytes": "32",
+ "value": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ }
+ }
+ }
+ }
+ }
+ },
+ {
+ "contract": "contracts/colony/ColonyExpenditure.sol:ColonyExpenditure",
+ "label": "chainNonRewardPotsTotals",
+ "offset": 0,
+ "slot": "41",
+ "type": {
+ "encoding": "mapping",
+ "key": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ },
+ "label": "mapping(uint256 => mapping(address => uint256))",
+ "numberOfBytes": "32",
+ "value": {
+ "encoding": "mapping",
+ "key": {
+ "encoding": "inplace",
+ "label": "address",
+ "numberOfBytes": "20"
+ },
+ "label": "mapping(address => uint256)",
+ "numberOfBytes": "32",
+ "value": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ }
+ }
+ }
}
]
}
\ No newline at end of file
diff --git a/.storage-layouts-normalized/contracts/colony/ColonyFunding.sol:ColonyFunding.json b/.storage-layouts-normalized/contracts/colony/ColonyFunding.sol:ColonyFunding.json
index 3fa29005de..1ee5a9a68c 100644
--- a/.storage-layouts-normalized/contracts/colony/ColonyFunding.sol:ColonyFunding.json
+++ b/.storage-layouts-normalized/contracts/colony/ColonyFunding.sol:ColonyFunding.json
@@ -506,9 +506,71 @@
"label": "uint256",
"numberOfBytes": "32"
}
+ },
+ {
+ "contract": "contracts/colony/ColonyFunding.sol:ColonyFunding",
+ "label": "chainBalances",
+ "offset": 0,
+ "slot": "5",
+ "type": {
+ "encoding": "mapping",
+ "key": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ },
+ "label": "mapping(uint256 => mapping(address => uint256))",
+ "numberOfBytes": "32",
+ "value": {
+ "encoding": "mapping",
+ "key": {
+ "encoding": "inplace",
+ "label": "address",
+ "numberOfBytes": "20"
+ },
+ "label": "mapping(address => uint256)",
+ "numberOfBytes": "32",
+ "value": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ }
+ }
+ }
+ },
+ {
+ "contract": "contracts/colony/ColonyFunding.sol:ColonyFunding",
+ "label": "chainPayouts",
+ "offset": 0,
+ "slot": "6",
+ "type": {
+ "encoding": "mapping",
+ "key": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ },
+ "label": "mapping(uint256 => mapping(address => uint256))",
+ "numberOfBytes": "32",
+ "value": {
+ "encoding": "mapping",
+ "key": {
+ "encoding": "inplace",
+ "label": "address",
+ "numberOfBytes": "20"
+ },
+ "label": "mapping(address => uint256)",
+ "numberOfBytes": "32",
+ "value": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ }
+ }
+ }
}
],
- "numberOfBytes": "160"
+ "numberOfBytes": "224"
}
}
},
@@ -1430,6 +1492,88 @@
"numberOfBytes": "32"
}
}
+ },
+ {
+ "contract": "contracts/colony/ColonyFunding.sol:ColonyFunding",
+ "label": "expenditureSlotChainPayouts",
+ "offset": 0,
+ "slot": "40",
+ "type": {
+ "encoding": "mapping",
+ "key": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ },
+ "label": "mapping(uint256 => mapping(uint256 => mapping(uint256 => mapping(address => uint256))))",
+ "numberOfBytes": "32",
+ "value": {
+ "encoding": "mapping",
+ "key": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ },
+ "label": "mapping(uint256 => mapping(uint256 => mapping(address => uint256)))",
+ "numberOfBytes": "32",
+ "value": {
+ "encoding": "mapping",
+ "key": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ },
+ "label": "mapping(uint256 => mapping(address => uint256))",
+ "numberOfBytes": "32",
+ "value": {
+ "encoding": "mapping",
+ "key": {
+ "encoding": "inplace",
+ "label": "address",
+ "numberOfBytes": "20"
+ },
+ "label": "mapping(address => uint256)",
+ "numberOfBytes": "32",
+ "value": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ }
+ }
+ }
+ }
+ }
+ },
+ {
+ "contract": "contracts/colony/ColonyFunding.sol:ColonyFunding",
+ "label": "chainNonRewardPotsTotals",
+ "offset": 0,
+ "slot": "41",
+ "type": {
+ "encoding": "mapping",
+ "key": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ },
+ "label": "mapping(uint256 => mapping(address => uint256))",
+ "numberOfBytes": "32",
+ "value": {
+ "encoding": "mapping",
+ "key": {
+ "encoding": "inplace",
+ "label": "address",
+ "numberOfBytes": "20"
+ },
+ "label": "mapping(address => uint256)",
+ "numberOfBytes": "32",
+ "value": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ }
+ }
+ }
}
]
}
\ No newline at end of file
diff --git a/.storage-layouts-normalized/contracts/colony/ColonyRewards.sol:ColonyRewards.json b/.storage-layouts-normalized/contracts/colony/ColonyRewards.sol:ColonyRewards.json
index 82d779f988..f20d4814fe 100644
--- a/.storage-layouts-normalized/contracts/colony/ColonyRewards.sol:ColonyRewards.json
+++ b/.storage-layouts-normalized/contracts/colony/ColonyRewards.sol:ColonyRewards.json
@@ -506,9 +506,71 @@
"label": "uint256",
"numberOfBytes": "32"
}
+ },
+ {
+ "contract": "contracts/colony/ColonyRewards.sol:ColonyRewards",
+ "label": "chainBalances",
+ "offset": 0,
+ "slot": "5",
+ "type": {
+ "encoding": "mapping",
+ "key": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ },
+ "label": "mapping(uint256 => mapping(address => uint256))",
+ "numberOfBytes": "32",
+ "value": {
+ "encoding": "mapping",
+ "key": {
+ "encoding": "inplace",
+ "label": "address",
+ "numberOfBytes": "20"
+ },
+ "label": "mapping(address => uint256)",
+ "numberOfBytes": "32",
+ "value": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ }
+ }
+ }
+ },
+ {
+ "contract": "contracts/colony/ColonyRewards.sol:ColonyRewards",
+ "label": "chainPayouts",
+ "offset": 0,
+ "slot": "6",
+ "type": {
+ "encoding": "mapping",
+ "key": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ },
+ "label": "mapping(uint256 => mapping(address => uint256))",
+ "numberOfBytes": "32",
+ "value": {
+ "encoding": "mapping",
+ "key": {
+ "encoding": "inplace",
+ "label": "address",
+ "numberOfBytes": "20"
+ },
+ "label": "mapping(address => uint256)",
+ "numberOfBytes": "32",
+ "value": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ }
+ }
+ }
}
],
- "numberOfBytes": "160"
+ "numberOfBytes": "224"
}
}
},
@@ -1430,6 +1492,88 @@
"numberOfBytes": "32"
}
}
+ },
+ {
+ "contract": "contracts/colony/ColonyRewards.sol:ColonyRewards",
+ "label": "expenditureSlotChainPayouts",
+ "offset": 0,
+ "slot": "40",
+ "type": {
+ "encoding": "mapping",
+ "key": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ },
+ "label": "mapping(uint256 => mapping(uint256 => mapping(uint256 => mapping(address => uint256))))",
+ "numberOfBytes": "32",
+ "value": {
+ "encoding": "mapping",
+ "key": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ },
+ "label": "mapping(uint256 => mapping(uint256 => mapping(address => uint256)))",
+ "numberOfBytes": "32",
+ "value": {
+ "encoding": "mapping",
+ "key": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ },
+ "label": "mapping(uint256 => mapping(address => uint256))",
+ "numberOfBytes": "32",
+ "value": {
+ "encoding": "mapping",
+ "key": {
+ "encoding": "inplace",
+ "label": "address",
+ "numberOfBytes": "20"
+ },
+ "label": "mapping(address => uint256)",
+ "numberOfBytes": "32",
+ "value": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ }
+ }
+ }
+ }
+ }
+ },
+ {
+ "contract": "contracts/colony/ColonyRewards.sol:ColonyRewards",
+ "label": "chainNonRewardPotsTotals",
+ "offset": 0,
+ "slot": "41",
+ "type": {
+ "encoding": "mapping",
+ "key": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ },
+ "label": "mapping(uint256 => mapping(address => uint256))",
+ "numberOfBytes": "32",
+ "value": {
+ "encoding": "mapping",
+ "key": {
+ "encoding": "inplace",
+ "label": "address",
+ "numberOfBytes": "20"
+ },
+ "label": "mapping(address => uint256)",
+ "numberOfBytes": "32",
+ "value": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ }
+ }
+ }
}
]
}
\ No newline at end of file
diff --git a/.storage-layouts-normalized/contracts/colony/ColonyRoles.sol:ColonyRoles.json b/.storage-layouts-normalized/contracts/colony/ColonyRoles.sol:ColonyRoles.json
index cffe687525..e9a38d86ee 100644
--- a/.storage-layouts-normalized/contracts/colony/ColonyRoles.sol:ColonyRoles.json
+++ b/.storage-layouts-normalized/contracts/colony/ColonyRoles.sol:ColonyRoles.json
@@ -506,9 +506,71 @@
"label": "uint256",
"numberOfBytes": "32"
}
+ },
+ {
+ "contract": "contracts/colony/ColonyRoles.sol:ColonyRoles",
+ "label": "chainBalances",
+ "offset": 0,
+ "slot": "5",
+ "type": {
+ "encoding": "mapping",
+ "key": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ },
+ "label": "mapping(uint256 => mapping(address => uint256))",
+ "numberOfBytes": "32",
+ "value": {
+ "encoding": "mapping",
+ "key": {
+ "encoding": "inplace",
+ "label": "address",
+ "numberOfBytes": "20"
+ },
+ "label": "mapping(address => uint256)",
+ "numberOfBytes": "32",
+ "value": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ }
+ }
+ }
+ },
+ {
+ "contract": "contracts/colony/ColonyRoles.sol:ColonyRoles",
+ "label": "chainPayouts",
+ "offset": 0,
+ "slot": "6",
+ "type": {
+ "encoding": "mapping",
+ "key": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ },
+ "label": "mapping(uint256 => mapping(address => uint256))",
+ "numberOfBytes": "32",
+ "value": {
+ "encoding": "mapping",
+ "key": {
+ "encoding": "inplace",
+ "label": "address",
+ "numberOfBytes": "20"
+ },
+ "label": "mapping(address => uint256)",
+ "numberOfBytes": "32",
+ "value": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ }
+ }
+ }
}
],
- "numberOfBytes": "160"
+ "numberOfBytes": "224"
}
}
},
@@ -1430,6 +1492,88 @@
"numberOfBytes": "32"
}
}
+ },
+ {
+ "contract": "contracts/colony/ColonyRoles.sol:ColonyRoles",
+ "label": "expenditureSlotChainPayouts",
+ "offset": 0,
+ "slot": "40",
+ "type": {
+ "encoding": "mapping",
+ "key": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ },
+ "label": "mapping(uint256 => mapping(uint256 => mapping(uint256 => mapping(address => uint256))))",
+ "numberOfBytes": "32",
+ "value": {
+ "encoding": "mapping",
+ "key": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ },
+ "label": "mapping(uint256 => mapping(uint256 => mapping(address => uint256)))",
+ "numberOfBytes": "32",
+ "value": {
+ "encoding": "mapping",
+ "key": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ },
+ "label": "mapping(uint256 => mapping(address => uint256))",
+ "numberOfBytes": "32",
+ "value": {
+ "encoding": "mapping",
+ "key": {
+ "encoding": "inplace",
+ "label": "address",
+ "numberOfBytes": "20"
+ },
+ "label": "mapping(address => uint256)",
+ "numberOfBytes": "32",
+ "value": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ }
+ }
+ }
+ }
+ }
+ },
+ {
+ "contract": "contracts/colony/ColonyRoles.sol:ColonyRoles",
+ "label": "chainNonRewardPotsTotals",
+ "offset": 0,
+ "slot": "41",
+ "type": {
+ "encoding": "mapping",
+ "key": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ },
+ "label": "mapping(uint256 => mapping(address => uint256))",
+ "numberOfBytes": "32",
+ "value": {
+ "encoding": "mapping",
+ "key": {
+ "encoding": "inplace",
+ "label": "address",
+ "numberOfBytes": "20"
+ },
+ "label": "mapping(address => uint256)",
+ "numberOfBytes": "32",
+ "value": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ }
+ }
+ }
}
]
}
\ No newline at end of file
diff --git a/.storage-layouts-normalized/contracts/colony/ColonyStorage.sol:ColonyStorage.json b/.storage-layouts-normalized/contracts/colony/ColonyStorage.sol:ColonyStorage.json
index 3c77c7ae35..449b9e4a62 100644
--- a/.storage-layouts-normalized/contracts/colony/ColonyStorage.sol:ColonyStorage.json
+++ b/.storage-layouts-normalized/contracts/colony/ColonyStorage.sol:ColonyStorage.json
@@ -506,9 +506,71 @@
"label": "uint256",
"numberOfBytes": "32"
}
+ },
+ {
+ "contract": "contracts/colony/ColonyStorage.sol:ColonyStorage",
+ "label": "chainBalances",
+ "offset": 0,
+ "slot": "5",
+ "type": {
+ "encoding": "mapping",
+ "key": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ },
+ "label": "mapping(uint256 => mapping(address => uint256))",
+ "numberOfBytes": "32",
+ "value": {
+ "encoding": "mapping",
+ "key": {
+ "encoding": "inplace",
+ "label": "address",
+ "numberOfBytes": "20"
+ },
+ "label": "mapping(address => uint256)",
+ "numberOfBytes": "32",
+ "value": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ }
+ }
+ }
+ },
+ {
+ "contract": "contracts/colony/ColonyStorage.sol:ColonyStorage",
+ "label": "chainPayouts",
+ "offset": 0,
+ "slot": "6",
+ "type": {
+ "encoding": "mapping",
+ "key": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ },
+ "label": "mapping(uint256 => mapping(address => uint256))",
+ "numberOfBytes": "32",
+ "value": {
+ "encoding": "mapping",
+ "key": {
+ "encoding": "inplace",
+ "label": "address",
+ "numberOfBytes": "20"
+ },
+ "label": "mapping(address => uint256)",
+ "numberOfBytes": "32",
+ "value": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ }
+ }
+ }
}
],
- "numberOfBytes": "160"
+ "numberOfBytes": "224"
}
}
},
@@ -1430,6 +1492,88 @@
"numberOfBytes": "32"
}
}
+ },
+ {
+ "contract": "contracts/colony/ColonyStorage.sol:ColonyStorage",
+ "label": "expenditureSlotChainPayouts",
+ "offset": 0,
+ "slot": "40",
+ "type": {
+ "encoding": "mapping",
+ "key": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ },
+ "label": "mapping(uint256 => mapping(uint256 => mapping(uint256 => mapping(address => uint256))))",
+ "numberOfBytes": "32",
+ "value": {
+ "encoding": "mapping",
+ "key": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ },
+ "label": "mapping(uint256 => mapping(uint256 => mapping(address => uint256)))",
+ "numberOfBytes": "32",
+ "value": {
+ "encoding": "mapping",
+ "key": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ },
+ "label": "mapping(uint256 => mapping(address => uint256))",
+ "numberOfBytes": "32",
+ "value": {
+ "encoding": "mapping",
+ "key": {
+ "encoding": "inplace",
+ "label": "address",
+ "numberOfBytes": "20"
+ },
+ "label": "mapping(address => uint256)",
+ "numberOfBytes": "32",
+ "value": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ }
+ }
+ }
+ }
+ }
+ },
+ {
+ "contract": "contracts/colony/ColonyStorage.sol:ColonyStorage",
+ "label": "chainNonRewardPotsTotals",
+ "offset": 0,
+ "slot": "41",
+ "type": {
+ "encoding": "mapping",
+ "key": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ },
+ "label": "mapping(uint256 => mapping(address => uint256))",
+ "numberOfBytes": "32",
+ "value": {
+ "encoding": "mapping",
+ "key": {
+ "encoding": "inplace",
+ "label": "address",
+ "numberOfBytes": "20"
+ },
+ "label": "mapping(address => uint256)",
+ "numberOfBytes": "32",
+ "value": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ }
+ }
+ }
}
]
}
\ No newline at end of file
diff --git a/.storage-layouts-normalized/contracts/colonyNetwork/ColonyNetwork.sol:ColonyNetwork.json b/.storage-layouts-normalized/contracts/colonyNetwork/ColonyNetwork.sol:ColonyNetwork.json
index efa08ea81b..b23f673dc1 100644
--- a/.storage-layouts-normalized/contracts/colonyNetwork/ColonyNetwork.sol:ColonyNetwork.json
+++ b/.storage-layouts-normalized/contracts/colonyNetwork/ColonyNetwork.sol:ColonyNetwork.json
@@ -305,11 +305,11 @@
"label": "uint256",
"numberOfBytes": "32"
},
- "label": "mapping(uint256 => struct ColonyNetworkDataTypes.Skill)",
+ "label": "mapping(uint256 => struct CommonDataTypes.Skill)",
"numberOfBytes": "32",
"value": {
"encoding": "inplace",
- "label": "struct ColonyNetworkDataTypes.Skill",
+ "label": "struct CommonDataTypes.Skill",
"members": [
{
"contract": "contracts/colonyNetwork/ColonyNetwork.sol:ColonyNetwork",
diff --git a/.storage-layouts-normalized/contracts/colonyNetwork/ColonyNetworkAuction.sol:ColonyNetworkAuction.json b/.storage-layouts-normalized/contracts/colonyNetwork/ColonyNetworkAuction.sol:ColonyNetworkAuction.json
index f09ac659e5..e2a0f8aded 100644
--- a/.storage-layouts-normalized/contracts/colonyNetwork/ColonyNetworkAuction.sol:ColonyNetworkAuction.json
+++ b/.storage-layouts-normalized/contracts/colonyNetwork/ColonyNetworkAuction.sol:ColonyNetworkAuction.json
@@ -305,11 +305,11 @@
"label": "uint256",
"numberOfBytes": "32"
},
- "label": "mapping(uint256 => struct ColonyNetworkDataTypes.Skill)",
+ "label": "mapping(uint256 => struct CommonDataTypes.Skill)",
"numberOfBytes": "32",
"value": {
"encoding": "inplace",
- "label": "struct ColonyNetworkDataTypes.Skill",
+ "label": "struct CommonDataTypes.Skill",
"members": [
{
"contract": "contracts/colonyNetwork/ColonyNetworkAuction.sol:ColonyNetworkAuction",
diff --git a/.storage-layouts-normalized/contracts/colonyNetwork/ColonyNetworkDeployer.sol:ColonyNetworkDeployer.json b/.storage-layouts-normalized/contracts/colonyNetwork/ColonyNetworkDeployer.sol:ColonyNetworkDeployer.json
index 205d16a0e5..f170b9070b 100644
--- a/.storage-layouts-normalized/contracts/colonyNetwork/ColonyNetworkDeployer.sol:ColonyNetworkDeployer.json
+++ b/.storage-layouts-normalized/contracts/colonyNetwork/ColonyNetworkDeployer.sol:ColonyNetworkDeployer.json
@@ -305,11 +305,11 @@
"label": "uint256",
"numberOfBytes": "32"
},
- "label": "mapping(uint256 => struct ColonyNetworkDataTypes.Skill)",
+ "label": "mapping(uint256 => struct CommonDataTypes.Skill)",
"numberOfBytes": "32",
"value": {
"encoding": "inplace",
- "label": "struct ColonyNetworkDataTypes.Skill",
+ "label": "struct CommonDataTypes.Skill",
"members": [
{
"contract": "contracts/colonyNetwork/ColonyNetworkDeployer.sol:ColonyNetworkDeployer",
diff --git a/.storage-layouts-normalized/contracts/colonyNetwork/ColonyNetworkENS.sol:ColonyNetworkENS.json b/.storage-layouts-normalized/contracts/colonyNetwork/ColonyNetworkENS.sol:ColonyNetworkENS.json
index e884e616d7..fde3772693 100644
--- a/.storage-layouts-normalized/contracts/colonyNetwork/ColonyNetworkENS.sol:ColonyNetworkENS.json
+++ b/.storage-layouts-normalized/contracts/colonyNetwork/ColonyNetworkENS.sol:ColonyNetworkENS.json
@@ -305,11 +305,11 @@
"label": "uint256",
"numberOfBytes": "32"
},
- "label": "mapping(uint256 => struct ColonyNetworkDataTypes.Skill)",
+ "label": "mapping(uint256 => struct CommonDataTypes.Skill)",
"numberOfBytes": "32",
"value": {
"encoding": "inplace",
- "label": "struct ColonyNetworkDataTypes.Skill",
+ "label": "struct CommonDataTypes.Skill",
"members": [
{
"contract": "contracts/colonyNetwork/ColonyNetworkENS.sol:ColonyNetworkENS",
diff --git a/.storage-layouts-normalized/contracts/colonyNetwork/ColonyNetworkExtensions.sol:ColonyNetworkExtensions.json b/.storage-layouts-normalized/contracts/colonyNetwork/ColonyNetworkExtensions.sol:ColonyNetworkExtensions.json
index a9bf72907d..543c70a6b4 100644
--- a/.storage-layouts-normalized/contracts/colonyNetwork/ColonyNetworkExtensions.sol:ColonyNetworkExtensions.json
+++ b/.storage-layouts-normalized/contracts/colonyNetwork/ColonyNetworkExtensions.sol:ColonyNetworkExtensions.json
@@ -305,11 +305,11 @@
"label": "uint256",
"numberOfBytes": "32"
},
- "label": "mapping(uint256 => struct ColonyNetworkDataTypes.Skill)",
+ "label": "mapping(uint256 => struct CommonDataTypes.Skill)",
"numberOfBytes": "32",
"value": {
"encoding": "inplace",
- "label": "struct ColonyNetworkDataTypes.Skill",
+ "label": "struct CommonDataTypes.Skill",
"members": [
{
"contract": "contracts/colonyNetwork/ColonyNetworkExtensions.sol:ColonyNetworkExtensions",
diff --git a/.storage-layouts-normalized/contracts/colonyNetwork/ColonyNetworkMining.sol:ColonyNetworkMining.json b/.storage-layouts-normalized/contracts/colonyNetwork/ColonyNetworkMining.sol:ColonyNetworkMining.json
index b8e05c9bc9..5ed5d8cde9 100644
--- a/.storage-layouts-normalized/contracts/colonyNetwork/ColonyNetworkMining.sol:ColonyNetworkMining.json
+++ b/.storage-layouts-normalized/contracts/colonyNetwork/ColonyNetworkMining.sol:ColonyNetworkMining.json
@@ -305,11 +305,11 @@
"label": "uint256",
"numberOfBytes": "32"
},
- "label": "mapping(uint256 => struct ColonyNetworkDataTypes.Skill)",
+ "label": "mapping(uint256 => struct CommonDataTypes.Skill)",
"numberOfBytes": "32",
"value": {
"encoding": "inplace",
- "label": "struct ColonyNetworkDataTypes.Skill",
+ "label": "struct CommonDataTypes.Skill",
"members": [
{
"contract": "contracts/colonyNetwork/ColonyNetworkMining.sol:ColonyNetworkMining",
diff --git a/.storage-layouts-normalized/contracts/colonyNetwork/ColonyNetworkSkills.sol:ColonyNetworkSkills.json b/.storage-layouts-normalized/contracts/colonyNetwork/ColonyNetworkSkills.sol:ColonyNetworkSkills.json
index e31cc4d380..ea8d893db2 100644
--- a/.storage-layouts-normalized/contracts/colonyNetwork/ColonyNetworkSkills.sol:ColonyNetworkSkills.json
+++ b/.storage-layouts-normalized/contracts/colonyNetwork/ColonyNetworkSkills.sol:ColonyNetworkSkills.json
@@ -305,11 +305,11 @@
"label": "uint256",
"numberOfBytes": "32"
},
- "label": "mapping(uint256 => struct ColonyNetworkDataTypes.Skill)",
+ "label": "mapping(uint256 => struct CommonDataTypes.Skill)",
"numberOfBytes": "32",
"value": {
"encoding": "inplace",
- "label": "struct ColonyNetworkDataTypes.Skill",
+ "label": "struct CommonDataTypes.Skill",
"members": [
{
"contract": "contracts/colonyNetwork/ColonyNetworkSkills.sol:ColonyNetworkSkills",
diff --git a/.storage-layouts-normalized/contracts/colonyNetwork/ColonyNetworkStorage.sol:ColonyNetworkStorage.json b/.storage-layouts-normalized/contracts/colonyNetwork/ColonyNetworkStorage.sol:ColonyNetworkStorage.json
index 14053448f0..20b5a83ab2 100644
--- a/.storage-layouts-normalized/contracts/colonyNetwork/ColonyNetworkStorage.sol:ColonyNetworkStorage.json
+++ b/.storage-layouts-normalized/contracts/colonyNetwork/ColonyNetworkStorage.sol:ColonyNetworkStorage.json
@@ -305,11 +305,11 @@
"label": "uint256",
"numberOfBytes": "32"
},
- "label": "mapping(uint256 => struct ColonyNetworkDataTypes.Skill)",
+ "label": "mapping(uint256 => struct CommonDataTypes.Skill)",
"numberOfBytes": "32",
"value": {
"encoding": "inplace",
- "label": "struct ColonyNetworkDataTypes.Skill",
+ "label": "struct CommonDataTypes.Skill",
"members": [
{
"contract": "contracts/colonyNetwork/ColonyNetworkStorage.sol:ColonyNetworkStorage",
diff --git a/.storage-layouts-normalized/contracts/common/Bytes4Includes.sol:Bytes4Includes.json b/.storage-layouts-normalized/contracts/common/CommonDataTypes.sol:CommonDataTypes.json
similarity index 100%
rename from .storage-layouts-normalized/contracts/common/Bytes4Includes.sol:Bytes4Includes.json
rename to .storage-layouts-normalized/contracts/common/CommonDataTypes.sol:CommonDataTypes.json
diff --git a/.storage-layouts-normalized/contracts/common/CallWithGuards.sol:CallWithGuards.json b/.storage-layouts-normalized/contracts/common/DomainReceiverManagement.sol:DomainReceiverManagement.json
similarity index 100%
rename from .storage-layouts-normalized/contracts/common/CallWithGuards.sol:CallWithGuards.json
rename to .storage-layouts-normalized/contracts/common/DomainReceiverManagement.sol:DomainReceiverManagement.json
diff --git a/.storage-layouts-normalized/contracts/common/ExtractCallData.sol:ExtractCallData.json b/.storage-layouts-normalized/contracts/common/mixins/Bytes4Includes.sol:Bytes4Includes.json
similarity index 100%
rename from .storage-layouts-normalized/contracts/common/ExtractCallData.sol:ExtractCallData.json
rename to .storage-layouts-normalized/contracts/common/mixins/Bytes4Includes.sol:Bytes4Includes.json
diff --git a/.storage-layouts-normalized/contracts/common/mixins/CallWithGuards.sol:CallWithGuards.json b/.storage-layouts-normalized/contracts/common/mixins/CallWithGuards.sol:CallWithGuards.json
new file mode 100644
index 0000000000..82b695cebb
--- /dev/null
+++ b/.storage-layouts-normalized/contracts/common/mixins/CallWithGuards.sol:CallWithGuards.json
@@ -0,0 +1,3 @@
+{
+ "storage": []
+}
\ No newline at end of file
diff --git a/.storage-layouts-normalized/contracts/common/mixins/ExtractCallData.sol:ExtractCallData.json b/.storage-layouts-normalized/contracts/common/mixins/ExtractCallData.sol:ExtractCallData.json
new file mode 100644
index 0000000000..82b695cebb
--- /dev/null
+++ b/.storage-layouts-normalized/contracts/common/mixins/ExtractCallData.sol:ExtractCallData.json
@@ -0,0 +1,3 @@
+{
+ "storage": []
+}
\ No newline at end of file
diff --git a/.storage-layouts-normalized/contracts/common/mixins/IsContract.sol:IsContract.json b/.storage-layouts-normalized/contracts/common/mixins/IsContract.sol:IsContract.json
new file mode 100644
index 0000000000..82b695cebb
--- /dev/null
+++ b/.storage-layouts-normalized/contracts/common/mixins/IsContract.sol:IsContract.json
@@ -0,0 +1,3 @@
+{
+ "storage": []
+}
\ No newline at end of file
diff --git a/.storage-layouts-normalized/contracts/testHelpers/FunctionsNotAvailableOnColony.sol:FunctionsNotAvailableOnColony.json b/.storage-layouts-normalized/contracts/testHelpers/FunctionsNotAvailableOnColony.sol:FunctionsNotAvailableOnColony.json
index 61de74236f..3afcf2daa8 100644
--- a/.storage-layouts-normalized/contracts/testHelpers/FunctionsNotAvailableOnColony.sol:FunctionsNotAvailableOnColony.json
+++ b/.storage-layouts-normalized/contracts/testHelpers/FunctionsNotAvailableOnColony.sol:FunctionsNotAvailableOnColony.json
@@ -506,9 +506,71 @@
"label": "uint256",
"numberOfBytes": "32"
}
+ },
+ {
+ "contract": "contracts/testHelpers/FunctionsNotAvailableOnColony.sol:FunctionsNotAvailableOnColony",
+ "label": "chainBalances",
+ "offset": 0,
+ "slot": "5",
+ "type": {
+ "encoding": "mapping",
+ "key": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ },
+ "label": "mapping(uint256 => mapping(address => uint256))",
+ "numberOfBytes": "32",
+ "value": {
+ "encoding": "mapping",
+ "key": {
+ "encoding": "inplace",
+ "label": "address",
+ "numberOfBytes": "20"
+ },
+ "label": "mapping(address => uint256)",
+ "numberOfBytes": "32",
+ "value": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ }
+ }
+ }
+ },
+ {
+ "contract": "contracts/testHelpers/FunctionsNotAvailableOnColony.sol:FunctionsNotAvailableOnColony",
+ "label": "chainPayouts",
+ "offset": 0,
+ "slot": "6",
+ "type": {
+ "encoding": "mapping",
+ "key": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ },
+ "label": "mapping(uint256 => mapping(address => uint256))",
+ "numberOfBytes": "32",
+ "value": {
+ "encoding": "mapping",
+ "key": {
+ "encoding": "inplace",
+ "label": "address",
+ "numberOfBytes": "20"
+ },
+ "label": "mapping(address => uint256)",
+ "numberOfBytes": "32",
+ "value": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ }
+ }
+ }
}
],
- "numberOfBytes": "160"
+ "numberOfBytes": "224"
}
}
},
@@ -1430,6 +1492,88 @@
"numberOfBytes": "32"
}
}
+ },
+ {
+ "contract": "contracts/testHelpers/FunctionsNotAvailableOnColony.sol:FunctionsNotAvailableOnColony",
+ "label": "expenditureSlotChainPayouts",
+ "offset": 0,
+ "slot": "40",
+ "type": {
+ "encoding": "mapping",
+ "key": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ },
+ "label": "mapping(uint256 => mapping(uint256 => mapping(uint256 => mapping(address => uint256))))",
+ "numberOfBytes": "32",
+ "value": {
+ "encoding": "mapping",
+ "key": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ },
+ "label": "mapping(uint256 => mapping(uint256 => mapping(address => uint256)))",
+ "numberOfBytes": "32",
+ "value": {
+ "encoding": "mapping",
+ "key": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ },
+ "label": "mapping(uint256 => mapping(address => uint256))",
+ "numberOfBytes": "32",
+ "value": {
+ "encoding": "mapping",
+ "key": {
+ "encoding": "inplace",
+ "label": "address",
+ "numberOfBytes": "20"
+ },
+ "label": "mapping(address => uint256)",
+ "numberOfBytes": "32",
+ "value": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ }
+ }
+ }
+ }
+ }
+ },
+ {
+ "contract": "contracts/testHelpers/FunctionsNotAvailableOnColony.sol:FunctionsNotAvailableOnColony",
+ "label": "chainNonRewardPotsTotals",
+ "offset": 0,
+ "slot": "41",
+ "type": {
+ "encoding": "mapping",
+ "key": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ },
+ "label": "mapping(uint256 => mapping(address => uint256))",
+ "numberOfBytes": "32",
+ "value": {
+ "encoding": "mapping",
+ "key": {
+ "encoding": "inplace",
+ "label": "address",
+ "numberOfBytes": "20"
+ },
+ "label": "mapping(address => uint256)",
+ "numberOfBytes": "32",
+ "value": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ }
+ }
+ }
}
]
}
\ No newline at end of file
diff --git a/.storage-layouts-normalized/contracts/testHelpers/LiFiFacetProxyMock.sol:LiFiFacetProxyMock.json b/.storage-layouts-normalized/contracts/testHelpers/LiFiFacetProxyMock.sol:LiFiFacetProxyMock.json
new file mode 100644
index 0000000000..82b695cebb
--- /dev/null
+++ b/.storage-layouts-normalized/contracts/testHelpers/LiFiFacetProxyMock.sol:LiFiFacetProxyMock.json
@@ -0,0 +1,3 @@
+{
+ "storage": []
+}
\ No newline at end of file
diff --git a/.storage-layouts-normalized/contracts/testHelpers/NoLimitSubdomains.sol:NoLimitSubdomains.json b/.storage-layouts-normalized/contracts/testHelpers/NoLimitSubdomains.sol:NoLimitSubdomains.json
index 5d5e24feb5..c60f47d217 100644
--- a/.storage-layouts-normalized/contracts/testHelpers/NoLimitSubdomains.sol:NoLimitSubdomains.json
+++ b/.storage-layouts-normalized/contracts/testHelpers/NoLimitSubdomains.sol:NoLimitSubdomains.json
@@ -506,9 +506,71 @@
"label": "uint256",
"numberOfBytes": "32"
}
+ },
+ {
+ "contract": "contracts/testHelpers/NoLimitSubdomains.sol:NoLimitSubdomains",
+ "label": "chainBalances",
+ "offset": 0,
+ "slot": "5",
+ "type": {
+ "encoding": "mapping",
+ "key": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ },
+ "label": "mapping(uint256 => mapping(address => uint256))",
+ "numberOfBytes": "32",
+ "value": {
+ "encoding": "mapping",
+ "key": {
+ "encoding": "inplace",
+ "label": "address",
+ "numberOfBytes": "20"
+ },
+ "label": "mapping(address => uint256)",
+ "numberOfBytes": "32",
+ "value": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ }
+ }
+ }
+ },
+ {
+ "contract": "contracts/testHelpers/NoLimitSubdomains.sol:NoLimitSubdomains",
+ "label": "chainPayouts",
+ "offset": 0,
+ "slot": "6",
+ "type": {
+ "encoding": "mapping",
+ "key": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ },
+ "label": "mapping(uint256 => mapping(address => uint256))",
+ "numberOfBytes": "32",
+ "value": {
+ "encoding": "mapping",
+ "key": {
+ "encoding": "inplace",
+ "label": "address",
+ "numberOfBytes": "20"
+ },
+ "label": "mapping(address => uint256)",
+ "numberOfBytes": "32",
+ "value": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ }
+ }
+ }
}
],
- "numberOfBytes": "160"
+ "numberOfBytes": "224"
}
}
},
@@ -1430,6 +1492,88 @@
"numberOfBytes": "32"
}
}
+ },
+ {
+ "contract": "contracts/testHelpers/NoLimitSubdomains.sol:NoLimitSubdomains",
+ "label": "expenditureSlotChainPayouts",
+ "offset": 0,
+ "slot": "40",
+ "type": {
+ "encoding": "mapping",
+ "key": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ },
+ "label": "mapping(uint256 => mapping(uint256 => mapping(uint256 => mapping(address => uint256))))",
+ "numberOfBytes": "32",
+ "value": {
+ "encoding": "mapping",
+ "key": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ },
+ "label": "mapping(uint256 => mapping(uint256 => mapping(address => uint256)))",
+ "numberOfBytes": "32",
+ "value": {
+ "encoding": "mapping",
+ "key": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ },
+ "label": "mapping(uint256 => mapping(address => uint256))",
+ "numberOfBytes": "32",
+ "value": {
+ "encoding": "mapping",
+ "key": {
+ "encoding": "inplace",
+ "label": "address",
+ "numberOfBytes": "20"
+ },
+ "label": "mapping(address => uint256)",
+ "numberOfBytes": "32",
+ "value": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ }
+ }
+ }
+ }
+ }
+ },
+ {
+ "contract": "contracts/testHelpers/NoLimitSubdomains.sol:NoLimitSubdomains",
+ "label": "chainNonRewardPotsTotals",
+ "offset": 0,
+ "slot": "41",
+ "type": {
+ "encoding": "mapping",
+ "key": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ },
+ "label": "mapping(uint256 => mapping(address => uint256))",
+ "numberOfBytes": "32",
+ "value": {
+ "encoding": "mapping",
+ "key": {
+ "encoding": "inplace",
+ "label": "address",
+ "numberOfBytes": "20"
+ },
+ "label": "mapping(address => uint256)",
+ "numberOfBytes": "32",
+ "value": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ }
+ }
+ }
}
]
}
\ No newline at end of file
diff --git a/contracts/bridging/IColonyBridge.sol b/contracts/bridging/IColonyBridge.sol
index 5a5d7eb470..7067e719e7 100644
--- a/contracts/bridging/IColonyBridge.sol
+++ b/contracts/bridging/IColonyBridge.sol
@@ -45,8 +45,13 @@ interface IColonyBridge {
/// @notice Function to send a message to the colony bridge on another chain
/// @param evmChainId The chain id to send the message to
+ /// @param destination The address of the contract on the other chain to send the message to
/// @param payload The message payload
/// @return bool Whether the message was sent successfully (to the best of the contract's knowledge,
/// in terms of the underlying bridge implementation)
- function sendMessage(uint256 evmChainId, bytes memory payload) external returns (bool);
+ function sendMessage(
+ uint256 evmChainId,
+ address destination,
+ bytes memory payload
+ ) external returns (bool);
}
diff --git a/contracts/bridging/ProxyColony.sol b/contracts/bridging/ProxyColony.sol
new file mode 100644
index 0000000000..464d1d7338
--- /dev/null
+++ b/contracts/bridging/ProxyColony.sol
@@ -0,0 +1,151 @@
+// SPDX-License-Identifier: GPL-3.0-or-later
+/*
+ This file is part of The Colony Network.
+
+ The Colony Network is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ The Colony Network is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with The Colony Network. If not, see .
+*/
+
+pragma solidity 0.8.28;
+pragma experimental ABIEncoderV2;
+
+import { CallWithGuards } from "../common/mixins/CallWithGuards.sol";
+import { DSAuth } from "./../../lib/dappsys/auth.sol";
+import { ERC20Extended } from "./../common/ERC20Extended.sol";
+import { Multicall } from "./../common/Multicall.sol";
+import { IColonyNetwork } from "./../colonyNetwork/IColonyNetwork.sol";
+import { ProxyColonyNetwork } from "./ProxyColonyNetwork.sol";
+import { DomainTokenReceiver } from "./../common/DomainTokenReceiver.sol";
+import { BasicMetaTransaction } from "./../common/BasicMetaTransaction.sol";
+
+contract ProxyColony is DSAuth, Multicall, CallWithGuards, BasicMetaTransaction {
+ // Address of the Resolver contract used by EtherRouter for lookups and routing
+ address resolver; // Storage slot 2 (from DSAuth there is authority and owner at storage slots 0 and 1 respectively)
+
+ mapping(address => uint256) metatransactionNonces;
+
+ // Token address => known balance
+ mapping(address => uint256) tokenBalances;
+
+ // Events
+
+ modifier onlyColonyBridge() {
+ require(ProxyColonyNetwork(owner).colonyBridgeAddress() == msgSender(), "colony-only-bridge");
+ _;
+ }
+
+ event DomainFundsClaimed(address token, uint256 domainId, uint256 balance);
+ event TransferMade(address token, address user, uint256 amount);
+
+ // Public functions
+
+ function claimColonyFunds(address _token) public {
+ uint256 balance = (_token == address(0x0))
+ ? address(this).balance
+ : ERC20Extended(_token).balanceOf(address(this));
+
+ require(balance >= tokenBalances[_token], "colony-shell-token-bookkeeping-error");
+ uint256 difference = balance - tokenBalances[_token];
+
+ tokenBalances[_token] = balance;
+
+ bytes memory payload = abi.encodeWithSignature(
+ "recordClaimedFundsFromBridge(uint256,address,uint256,uint256)",
+ block.chainid,
+ _token,
+ 1,
+ difference
+ );
+ ProxyColonyNetwork(owner).bridgeMessage(payload);
+
+ emit DomainFundsClaimed(_token, 1, balance);
+ }
+
+ function claimDomainFunds(address _token, uint256 _domainId) public {
+ address domainTokenReceiverAddress = ProxyColonyNetwork(owner)
+ .idempotentDeployDomainTokenReceiver(_domainId);
+
+ uint256 balance = (_token == address(0x0))
+ ? address(domainTokenReceiverAddress).balance
+ : ERC20Extended(_token).balanceOf(address(domainTokenReceiverAddress));
+
+ if (_token == address(0x0)) {
+ DomainTokenReceiver(domainTokenReceiverAddress).transferChainNativeToColony();
+ } else {
+ DomainTokenReceiver(domainTokenReceiverAddress).approveTokenToColony(_token);
+ // slither-disable-next-line arbitrary-send-erc20
+ require(
+ ERC20Extended(_token).transferFrom(domainTokenReceiverAddress, address(this), balance),
+ "colony-funding-transfer-failed"
+ );
+ }
+
+ bytes memory payload = abi.encodeWithSignature(
+ "recordClaimedFundsFromBridge(uint256,address,uint256,uint256)",
+ block.chainid,
+ _token,
+ _domainId,
+ balance
+ );
+
+ ProxyColonyNetwork(owner).bridgeMessage(payload);
+
+ emit DomainFundsClaimed(_token, _domainId, balance);
+ }
+
+ // TODO: secure this function
+ function transferFromBridge(
+ address _token,
+ address _recipient,
+ uint256 _amount
+ ) public onlyColonyBridge {
+ tokenBalances[_token] -= _amount;
+
+ if (_token == address(0x0)) {
+ payable(_recipient).transfer(_amount);
+ } else {
+ require(ERC20Extended(_token).transfer(_recipient, _amount), "colony-proxy-transfer-failed");
+ }
+
+ emit TransferMade(_token, _recipient, _amount);
+ }
+
+ function makeArbitraryTransaction(
+ address _target,
+ bytes memory _payload
+ ) public onlyColonyBridge {
+ address bridgeAddress = ProxyColonyNetwork(owner).colonyBridgeAddress();
+ // TODO: Stop, or otherwise handle, approve / transferFrom
+ require(_target != bridgeAddress, "colony-cannot-target-bridge");
+ require(_target != owner, "colony-cannot-target-network");
+ require(_target != address(this), "colony-cannot-target-self");
+ (bool success, bytes memory returndata) = callWithGuards(_target, _payload);
+
+ // Note that this is not a require because returndata might not be a string, and if we try
+ // to decode it we'll get a revert.
+ if (!success) {
+ revert(abi.decode(returndata, (string)));
+ }
+ }
+
+ // Overloading functions from BasicMetaTransaction
+ function getMetatransactionNonce(address _user) public view override returns (uint256 nonce) {
+ return metatransactionNonces[_user];
+ }
+
+ // NB if implementing this functionality in a contract with recovery mode,
+ // you MUST prevent the metatransaction nonces from being editable with recovery mode.
+ function incrementMetatransactionNonce(address _user) internal override {
+ metatransactionNonces[_user] += 1;
+ }
+}
diff --git a/contracts/bridging/ProxyColonyNetwork.sol b/contracts/bridging/ProxyColonyNetwork.sol
new file mode 100644
index 0000000000..09a2186385
--- /dev/null
+++ b/contracts/bridging/ProxyColonyNetwork.sol
@@ -0,0 +1,128 @@
+// SPDX-License-Identifier: GPL-3.0-or-later
+/*
+ This file is part of The Colony Network.
+
+ The Colony Network is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ The Colony Network is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with The Colony Network. If not, see .
+*/
+
+pragma solidity 0.8.28;
+pragma experimental ABIEncoderV2;
+
+import { BasicMetaTransaction } from "./../common/BasicMetaTransaction.sol";
+import { CallWithGuards } from "../common/mixins/CallWithGuards.sol";
+import { DSAuth } from "./../../lib/dappsys/auth.sol";
+import { ERC20Extended } from "./../common/ERC20Extended.sol";
+import { Multicall } from "./../common/Multicall.sol";
+import { IColonyNetwork } from "./../colonyNetwork/IColonyNetwork.sol";
+import { EtherRouterCreate3 } from "./../common/EtherRouterCreate3.sol";
+import { ICreateX } from "./../../lib/createx/src/ICreateX.sol";
+import { EtherRouter } from "./../common/EtherRouter.sol";
+import { IColonyBridge } from "./IColonyBridge.sol";
+import { DomainReceiverManagement } from "./../common/DomainReceiverManagement.sol";
+
+contract ProxyColonyNetwork is DSAuth, Multicall, CallWithGuards, DomainReceiverManagement {
+ address resolver; // Storage slot 2 (from DSAuth there is authority and owner at storage slots 0 and 1 respectively)
+
+ address public colonyBridgeAddress;
+ uint256 public homeChainId;
+ address public proxyColonyResolverAddress;
+ mapping(address => bool) public proxyColonies;
+ address public domainTokenReceiverResolver;
+
+ /// @notice Event logged when the colony network has data about a bridge contract set.
+ /// @param bridgeAddress The address of the bridge contract that will be interacted with
+ event BridgeSet(address bridgeAddress);
+
+ /// @notice Event logged when a new proxy colony is deployed.
+ /// @param proxyColony The address of the newly deployed proxy colony
+ event ProxyColonyDeployed(address proxyColony);
+
+ modifier onlyColony() {
+ require(msgSenderIsColony(), "colony-network-caller-must-be-proxy-colony");
+ _;
+ }
+
+ modifier onlyColonyBridge() {
+ require(msgSender() == colonyBridgeAddress, "colony-network-caller-must-be-colony-bridge");
+ _;
+ }
+
+ modifier ownerOrBridge() {
+ require(
+ msgSender() == colonyBridgeAddress || msgSender() == owner,
+ "colony-network-caller-must-be-owner-or-bridge"
+ );
+ _;
+ }
+
+ function setColonyBridgeAddress(address _bridgeAddress) public ownerOrBridge {
+ // TODO: Move this somewhere else to guard against unsupported chainids
+ // require(_chainId <= type(uint128).max, "colony-network-chainid-too-large");
+
+ colonyBridgeAddress = _bridgeAddress;
+ // TODO: Move this to where the first
+
+ emit BridgeSet(_bridgeAddress);
+ }
+
+ function setProxyColonyResolverAddress(address _resolver) public auth {
+ proxyColonyResolverAddress = _resolver;
+ }
+
+ function setHomeChainId(uint256 _homeChainId) public auth {
+ homeChainId = _homeChainId;
+ }
+
+ function getDomainTokenReceiverResolver() public view override returns (address) {
+ return domainTokenReceiverResolver;
+ }
+
+ function msgSenderIsColony() internal view override returns (bool) {
+ return proxyColonies[msgSender()];
+ }
+
+ function setDomainTokenReceiverResolver(address _resolver) public auth {
+ domainTokenReceiverResolver = _resolver;
+ }
+
+ function isStopped() internal pure override returns (bool) {
+ return false;
+ }
+
+ function createProxyColonyFromBridge(bytes32 _salt) public onlyColonyBridge {
+ EtherRouter etherRouter = EtherRouter(
+ payable(
+ ICreateX(CREATEX_ADDRESS).deployCreate3AndInit(
+ _salt,
+ type(EtherRouterCreate3).creationCode,
+ abi.encodeWithSignature("setOwner(address)", (address(this))),
+ ICreateX.Values(0, 0)
+ )
+ )
+ );
+
+ proxyColonies[address(etherRouter)] = true;
+
+ etherRouter.setResolver(proxyColonyResolverAddress); // ignore-swc-113
+
+ emit ProxyColonyDeployed(address(etherRouter));
+ }
+
+ function bridgeMessage(bytes memory _payload) public onlyColony {
+ require(
+ IColonyBridge(colonyBridgeAddress).sendMessage(homeChainId, msg.sender, _payload),
+ "colony-network-bridge-message-failed"
+ );
+ }
+}
diff --git a/contracts/bridging/WormholeBridgeForColony.sol b/contracts/bridging/WormholeBridgeForColony.sol
index 13674d4a8a..eaf03cb7a3 100644
--- a/contracts/bridging/WormholeBridgeForColony.sol
+++ b/contracts/bridging/WormholeBridgeForColony.sol
@@ -21,10 +21,12 @@ pragma solidity 0.8.28;
import { IWormhole } from "../../lib/wormhole/ethereum/contracts/interfaces/IWormhole.sol";
import { IColonyNetwork } from "../colonyNetwork/IColonyNetwork.sol";
import { IColonyBridge } from "./IColonyBridge.sol";
-import { CallWithGuards } from "../common/CallWithGuards.sol";
+import { CallWithGuards } from "../common/mixins/CallWithGuards.sol";
import { DSAuth } from "../../lib/dappsys/auth.sol";
contract WormholeBridgeForColony is DSAuth, IColonyBridge, CallWithGuards {
+ event WormholeMessageReceived(uint16 emitterChainId, bytes32 emitterAddress, uint64 sequence);
+
address public colonyNetwork;
IWormhole public wormhole;
@@ -93,6 +95,7 @@ contract WormholeBridgeForColony is DSAuth, IColonyBridge, CallWithGuards {
require(valid, reason);
// Check came from a known colony bridge
+
require(
wormholeAddressToEVMAddress(wormholeMessage.emitterAddress) ==
colonyBridges[wormholeMessage.emitterChainId],
@@ -101,10 +104,22 @@ contract WormholeBridgeForColony is DSAuth, IColonyBridge, CallWithGuards {
// We ignore sequence numbers - bridging out of order is okay, because we have our own way of handling that
- // Make the call requested to the colony network
+ bytes memory payload = wormholeMessage.payload;
+ // Strip off the chain id prefix, and make sure we are on that chain Id
+ uint256 destinationChainId;
+ address destinationAddress;
+ bytes memory payloadWithoutChainId;
+
+ (destinationChainId, destinationAddress, payloadWithoutChainId) = abi.decode(
+ payload,
+ (uint256, address, bytes)
+ );
+
+ require(destinationChainId == block.chainid, "colony-bridge-destination-chain-id-mismatch");
+ // Make the call requested to the destination address
(bool success, bytes memory returndata) = callWithGuards(
- colonyNetwork,
- wormholeMessage.payload
+ destinationAddress,
+ payloadWithoutChainId
);
// Note that this is not a require because returndata might not be a string, and if we try
@@ -112,17 +127,30 @@ contract WormholeBridgeForColony is DSAuth, IColonyBridge, CallWithGuards {
if (!success) {
revert(abi.decode(returndata, (string)));
}
+
+ emit WormholeMessageReceived(
+ wormholeMessage.emitterChainId,
+ wormholeMessage.emitterAddress,
+ wormholeMessage.sequence
+ );
}
function sendMessage(
uint256 _evmChainId,
+ address _destination,
bytes memory _payload
) public onlyColonyNetwork returns (bool) {
require(supportedEvmChainId(_evmChainId), "colony-bridge-not-known-chain");
// This returns a sequence, but we don't care about it
// The first sequence ID is, I believe 0, so all return values are potentially valid
// slither-disable-next-line unused-return
- try wormhole.publishMessage(0, _payload, 0) {
+
+ // For wormhole, we prefix the supplied payload with the _evmChainId
+ // This is because wormhole is a generic bridge, and we need to tell it which chain to send to
+
+ // We also prefix with the destination address, which we assume is the same as the sender.
+ // slither-disable-next-line unused-return
+ try wormhole.publishMessage(0, abi.encode(_evmChainId, _destination, _payload), 0) {
return true;
} catch {
return false;
diff --git a/contracts/colony/Colony.sol b/contracts/colony/Colony.sol
index 7aa19ac578..7539b4103b 100755
--- a/contracts/colony/Colony.sol
+++ b/contracts/colony/Colony.sol
@@ -322,6 +322,40 @@ contract Colony is BasicMetaTransaction, Multicall, ColonyStorage, PatriciaTreeP
sig = bytes4(keccak256("editAllowedDomainReputationReceipt(uint256,uint256,bool)"));
colonyAuthority.setRoleCapability(uint8(ColonyRole.Root), address(this), sig, true);
+
+ sig = bytes4(
+ keccak256("setExpenditurePayout(uint256,uint256,uint256,uint256,uint256,address,uint256)")
+ );
+ colonyAuthority.setRoleCapability(uint8(ColonyRole.Arbitration), address(this), sig, true);
+
+ sig = bytes4(
+ keccak256("moveFundsBetweenPots(uint256,uint256,uint256,uint256,uint256,uint256,address)")
+ );
+ colonyAuthority.setRoleCapability(uint8(ColonyRole.Funding), address(this), sig, true);
+
+ sig = bytes4(keccak256("makeProxyArbitraryTransaction(uint256,address,bytes)"));
+ colonyAuthority.setRoleCapability(uint8(ColonyRole.Root), address(this), sig, true);
+
+ sig = bytes4(keccak256("multicallProxyNetwork(uint256,bytes[])"));
+ colonyAuthority.setRoleCapability(uint8(ColonyRole.Root), address(this), sig, true);
+
+ sig = bytes4(
+ keccak256("exchangeTokensViaLiFi(uint256,uint256,uint256,bytes,uint256,address,uint256)")
+ );
+ colonyAuthority.setRoleCapability(uint8(ColonyRole.Funding), address(this), sig, true);
+
+ sig = bytes4(
+ keccak256(
+ "exchangeProxyHeldTokensViaLiFi(uint256,uint256,uint256,bytes,uint256,uint256,address,uint256)"
+ )
+ );
+ colonyAuthority.setRoleCapability(uint8(ColonyRole.Funding), address(this), sig, true);
+ }
+
+ function createProxyColony(uint256 _destinationChainId, bytes32 _salt) public stoppable {
+ IColonyNetwork(colonyNetworkAddress).createProxyColony(_destinationChainId, _salt);
+
+ emit ProxyColonyRequested(msgSender(), _destinationChainId, _salt);
}
function getMetatransactionNonce(address _user) public view override returns (uint256 nonce) {
diff --git a/contracts/colony/ColonyArbitraryTransaction.sol b/contracts/colony/ColonyArbitraryTransaction.sol
index 5cbbb1f693..5b82a956d6 100644
--- a/contracts/colony/ColonyArbitraryTransaction.sol
+++ b/contracts/colony/ColonyArbitraryTransaction.sol
@@ -44,6 +44,33 @@ contract ColonyArbitraryTransaction is ColonyStorage {
return res;
}
+ function makeProxyArbitraryTransaction(
+ uint256 _chainId,
+ address _destination,
+ bytes memory _action
+ ) public stoppable auth returns (bool) {
+ if (_destination == address(this)) {
+ IColonyNetwork(colonyNetworkAddress).bridgeMessage(_chainId, _action);
+ } else {
+ bytes memory payload = abi.encodeWithSignature(
+ "makeArbitraryTransaction(address,bytes)",
+ _destination,
+ _action
+ );
+ IColonyNetwork(colonyNetworkAddress).bridgeMessage(_chainId, payload);
+ }
+ }
+
+ function multicallProxyNetwork(
+ uint256 _chainId,
+ bytes[] memory _actions
+ ) public stoppable auth returns (bool) {
+ bytes memory payload = abi.encodeWithSignature("multicall(bytes[])", _actions);
+
+ IColonyNetwork(colonyNetworkAddress).bridgeMessageToNetwork(_chainId, payload);
+ return true;
+ }
+
function makeArbitraryTransactions(
address[] memory _targets,
bytes[] memory _actions,
diff --git a/contracts/colony/ColonyAuthority.sol b/contracts/colony/ColonyAuthority.sol
index b0c217adea..b6f840e472 100644
--- a/contracts/colony/ColonyAuthority.sol
+++ b/contracts/colony/ColonyAuthority.sol
@@ -137,6 +137,13 @@ contract ColonyAuthority is CommonAuthority {
// Added in colony v??
addRoleCapability(ROOT_ROLE, "editAllowedDomainReputationReceipt(uint256,uint256,bool)");
+
+ addRoleCapability(ARBITRATION_ROLE, "setExpenditurePayout(uint256,uint256,uint256,uint256,uint256,address,uint256)");
+ addRoleCapability(FUNDING_ROLE, "moveFundsBetweenPots(uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,address)");
+ addRoleCapability(ROOT_ROLE, "makeProxyArbitraryTransaction(uint256,address,bytes)");
+ addRoleCapability(ROOT_ROLE, "multicallProxyNetwork(uint256,bytes[])");
+
+ addRoleCapability(FUNDING_ROLE, "exchangeTokensViaLiFi(uint256,uint256,uint256,bytes,uint256,uint256,address,uint256)");
}
function addRoleCapability(uint8 role, bytes memory sig) private {
diff --git a/contracts/colony/ColonyDataTypes.sol b/contracts/colony/ColonyDataTypes.sol
index cf8267e228..764f9c74eb 100755
--- a/contracts/colony/ColonyDataTypes.sol
+++ b/contracts/colony/ColonyDataTypes.sol
@@ -18,8 +18,10 @@
pragma solidity 0.8.28;
+import { CommonDataTypes } from "./../common/CommonDataTypes.sol";
+
// prettier-ignore
-interface ColonyDataTypes {
+interface ColonyDataTypes is CommonDataTypes {
// Events
/// @notice Event logged when Colony is initialised
@@ -53,8 +55,9 @@ interface ColonyDataTypes {
/// @param fromPot The source funding pot
/// @param toPot The targer funding pot
/// @param amount The amount that was transferred
+ /// @param chainId The chain id of the token being transferred
/// @param token The token address being transferred
- event ColonyFundsMovedBetweenFundingPots(address agent, uint256 indexed fromPot, uint256 indexed toPot, uint256 amount, address token);
+ event ColonyFundsMovedBetweenFundingPots(address agent, uint256 indexed fromPot, uint256 indexed toPot, uint256 amount, uint256 chainId, address token);
/// @notice Event logged when colony funds are moved to the top-level domain pot
/// @param agent The address that is responsible for triggering this event
@@ -148,9 +151,10 @@ interface ColonyDataTypes {
/// @param agent The address that is responsible for triggering this event
/// @param expenditureId Id of the expenditure
/// @param slot Expenditure slot of the payout being changed
+ /// @param chainId Chain id of the token being paid out
/// @param token Token of the payout funding
/// @param amount Amount of the payout funding
- event ExpenditurePayoutSet(address agent, uint256 indexed expenditureId, uint256 indexed slot, address indexed token, uint256 amount);
+ event ExpenditurePayoutSet(address agent, uint256 indexed expenditureId, uint256 indexed slot, uint256 chainId, address indexed token, uint256 amount);
/// @notice Event logged when an expenditure slot claim delay changes
/// @param agent The address that is responsible for triggering this event
@@ -269,7 +273,14 @@ interface ColonyDataTypes {
/// @param slot Expenditure slot of the payout claimed
/// @param token Token of the payout claim
/// @param tokenPayout Amount of the payout claimed, after network fee was deducted
- event PayoutClaimed(address agent, uint256 id, uint256 slot, address token, uint256 tokenPayout);
+ event PayoutClaimed(address agent, uint256 id, uint256 slot, uint256 chainId, address token, uint256 tokenPayout);
+
+ /// @notice Event logged when a colony requests a proxy colony deployment
+ /// @param agent The address that is responsible for triggering this event
+ /// @param destinationChainId The chain id of the destination chain
+ /// @param salt The salt used to generate the proxy address
+ /// @dev The address corresponding to the salt must be this colony's address
+ event ProxyColonyRequested(address agent, uint256 destinationChainId, bytes32 salt);
// Structs
@@ -326,6 +337,12 @@ interface ColonyDataTypes {
// Map any assigned payouts from this pot
mapping (address => uint256) payouts;
uint256 payoutsWeCannotMake;
+
+ // Chainid => tokenAddress => balance
+ mapping (uint256 => mapping (address => uint256)) chainBalances;
+
+ // Chainid => tokenAddress => payouts
+ mapping (uint256 => mapping (address => uint256)) chainPayouts;
}
struct Domain {
@@ -436,6 +453,8 @@ interface ColonyDataTypes {
/// @param paymentId Id of the payment
event PaymentFinalized(address agent, uint256 indexed paymentId);
+ event ProxyColonyFundsClaimed(uint256 _chainId, address _token, uint256 _amount);
+
// Deprecated Task and Payment structs
enum TaskRatings { None, Unsatisfactory, Satisfactory, Excellent }
diff --git a/contracts/colony/ColonyExpenditure.sol b/contracts/colony/ColonyExpenditure.sol
index 8019e1e6e3..0b10a7d360 100644
--- a/contracts/colony/ColonyExpenditure.sol
+++ b/contracts/colony/ColonyExpenditure.sol
@@ -336,14 +336,6 @@ contract ColonyExpenditure is ColonyStorage {
expenditureSlot = expenditureSlots[_id][_slot];
}
- function getExpenditureSlotPayout(
- uint256 _id,
- uint256 _slot,
- address _token
- ) public view returns (uint256) {
- return expenditureSlotPayouts[_id][_slot][_token];
- }
-
// Internal functions
bool constant MAPPING = false;
diff --git a/contracts/colony/ColonyFunding.sol b/contracts/colony/ColonyFunding.sol
index fc2473f8e3..f23ad54dcc 100755
--- a/contracts/colony/ColonyFunding.sol
+++ b/contracts/colony/ColonyFunding.sol
@@ -22,8 +22,11 @@ pragma experimental "ABIEncoderV2";
import { ITokenLocking } from "./../tokenLocking/ITokenLocking.sol";
import { ColonyStorage } from "./ColonyStorage.sol";
import { ERC20Extended } from "./../common/ERC20Extended.sol";
+import { ERC20 } from "./../../lib/dappsys/erc20.sol";
import { IColonyNetwork } from "./../colonyNetwork/IColonyNetwork.sol";
+import { IColony } from "./IColony.sol";
import { DomainTokenReceiver } from "./../common/DomainTokenReceiver.sol";
+import { ProxyColony } from "./../bridging/ProxyColony.sol";
contract ColonyFunding is
ColonyStorage // ignore-swc-123
@@ -40,6 +43,32 @@ contract ColonyFunding is
uint256 _toPot,
uint256 _amount,
address _token
+ ) public stoppable {
+ moveFundsBetweenPots(
+ _permissionDomainId,
+ _childSkillIndex,
+ _domainId,
+ _fromChildSkillIndex,
+ _toChildSkillIndex,
+ _fromPot,
+ _toPot,
+ _amount,
+ block.chainid,
+ _token
+ );
+ }
+
+ function moveFundsBetweenPots(
+ uint256 _permissionDomainId,
+ uint256 _childSkillIndex,
+ uint256 _domainId,
+ uint256 _fromChildSkillIndex,
+ uint256 _toChildSkillIndex,
+ uint256 _fromPot,
+ uint256 _toPot,
+ uint256 _amount,
+ uint256 _chainId,
+ address _token
)
public
stoppable
@@ -56,7 +85,7 @@ contract ColonyFunding is
"colony-invalid-domain-inheritance"
);
- moveFundsBetweenPotsFunctionality(_fromPot, _toPot, _amount, _token);
+ moveFundsBetweenPotsFunctionality(_fromPot, _toPot, _amount, _chainId, _token);
}
function moveFundsBetweenPots(
@@ -75,7 +104,16 @@ contract ColonyFunding is
authDomain(_permissionDomainId, _toChildSkillIndex, getDomainFromFundingPot(_toPot))
validFundingTransfer(_fromPot, _toPot)
{
- moveFundsBetweenPotsFunctionality(_fromPot, _toPot, _amount, _token);
+ moveFundsBetweenPotsFunctionality(_fromPot, _toPot, _amount, block.chainid, _token);
+ }
+
+ function claimColonyFunds(uint256 _chainId, address _token) public stoppable {
+ if (_chainId == block.chainid) {
+ claimColonyFunds(_token);
+ } else {
+ bytes memory payload = abi.encodeWithSignature("claimColonyFunds(address)", _token);
+ IColony(address(this)).makeProxyArbitraryTransaction(_chainId, address(this), payload);
+ }
}
function claimColonyFunds(address _token) public stoppable {
@@ -86,13 +124,13 @@ contract ColonyFunding is
// It's ether
toClaim =
(address(this).balance - nonRewardPotsTotal[_token]) -
- fundingPots[0].balance[_token];
+ getFundingPotBalance(0, _token);
} else {
// Assume it's an ERC 20 token.
ERC20Extended targetToken = ERC20Extended(_token);
toClaim =
(targetToken.balanceOf(address(this)) - nonRewardPotsTotal[_token]) -
- fundingPots[0].balance[_token]; // ignore-swc-123
+ getFundingPotBalance(0, _token); // ignore-swc-123
}
feeToPay = toClaim / getRewardInverse(); // ignore-swc-110 . This variable is set when the colony is
@@ -100,9 +138,10 @@ contract ColonyFunding is
// to 0 via recovery mode, but a) That's not why MythX is balking here and b) There's only so much we can stop people being
// able to do with recovery mode.
remainder = toClaim - feeToPay;
- nonRewardPotsTotal[_token] += remainder;
- fundingPots[1].balance[_token] += remainder;
- fundingPots[0].balance[_token] += feeToPay;
+ incrementNonRewardPotsTotal(block.chainid, _token, remainder);
+ // nonRewardPotsTotal[_token] += remainder;
+ incrementFundingPotBalance(0, block.chainid, _token, feeToPay);
+ incrementFundingPotBalance(1, block.chainid, _token, remainder);
emit ColonyFundsClaimed(msgSender(), _token, feeToPay, remainder);
}
@@ -125,9 +164,11 @@ contract ColonyFunding is
// to 0 via recovery mode, but a) That's not why MythX is balking here and b) There's only so much we can stop people being
// able to do with recovery mode.
uint256 remainder = claimAmount - feeToPay;
- nonRewardPotsTotal[_token] += remainder;
+ incrementNonRewardPotsTotal(block.chainid, _token, remainder);
+ // nonRewardPotsTotal[_token] += remainder;
- fundingPots[0].balance[_token] += feeToPay;
+ // fundingPots[0].balance[_token] += feeToPay;
+ incrementFundingPotBalance(0, block.chainid, _token, feeToPay);
uint256 fundingPotId = domains[_domainId].fundingPotId;
uint256 approvedAmount = domainReputationApproval[_domainId];
@@ -188,8 +229,136 @@ contract ColonyFunding is
return domainReputationApproval[_domainId];
}
+ address constant LIFI_ADDRESS = 0x1231DEB6f5749EF6cE6943a275A1D3E7486F4EaE;
+
+ function exchangeTokensViaLiFi(
+ uint256 _permissionDomainId,
+ uint256 _childSkillIndex,
+ uint256 _domainId,
+ bytes memory _txdata,
+ uint256 _value,
+ uint256 _chainId,
+ address _token,
+ uint256 _amount
+ ) public stoppable authDomain(_permissionDomainId, _childSkillIndex, _domainId) {
+ // TODO: Colony Network fee
+
+ Domain storage d = domains[_domainId];
+
+ // Check the domain has enough for what is
+ if (_token == address(0x0)) {
+ require(
+ _value + _amount <= getFundingPotBalance(d.fundingPotId, _chainId, _token),
+ "colony-insufficient-funds"
+ );
+ } else {
+ require(
+ _amount <= getFundingPotBalance(d.fundingPotId, _chainId, _token),
+ "colony-insufficient-funds"
+ );
+ require(
+ _value <= getFundingPotBalance(d.fundingPotId, _chainId, address(0x0)),
+ "colony-insufficient-funds"
+ );
+ }
+
+ // Deduct the amount from the domain
+ decrementFundingPotBalance(d.fundingPotId, _chainId, _token, _amount);
+
+ // Deduct the value from the domain
+ decrementFundingPotBalance(d.fundingPotId, _chainId, address(0x0), _value);
+
+ // Build and send the transaction
+ if (_token == address(0)) {
+ revert("not yet implemented");
+ } else {
+ if (block.chainid == _chainId) {
+ if (_domainId == 1) {
+ // Check that we have enough not-already-approved tokens
+ require(
+ getFundingPotBalance(d.fundingPotId, _token) >= tokenApprovalTotals[_token] + _amount,
+ "colony-insufficient-funds"
+ );
+ }
+
+ uint256 priorApproval = ERC20Extended(_token).allowance(address(this), LIFI_ADDRESS);
+
+ require(
+ ERC20Extended(_token).approve(LIFI_ADDRESS, _amount + priorApproval),
+ "colony-approve-failed"
+ );
+ (bool success, ) = LIFI_ADDRESS.call{ value: _value }(_txdata);
+
+ require(success, "colony-exchange-tokens-failed");
+
+ // Check the allowances afterwards, ensuring that at least some of the tokens we approved were spent by
+ // the LiFi transaction - if not, a different token might have been spent, so revert.
+ uint256 postApproval = ERC20Extended(_token).allowance(address(this), LIFI_ADDRESS);
+ require(_amount + priorApproval > postApproval, "colony-unexpected-exchange");
+ require(postApproval >= priorApproval, "colony-more-than-intended-allowance-used");
+
+ // If the LiFi transaction didn't use all the tokens, reduce the allowance back to what it was before
+ if (postApproval > priorApproval) {
+ require(
+ ERC20Extended(_token).approve(LIFI_ADDRESS, priorApproval),
+ "colony-post-exchange-approve-failed"
+ );
+ }
+ } else {
+ // Exchange is to happen on another chain
+ bytes[] memory actions = new bytes[](2);
+
+ actions[0] = abi.encodeCall(
+ ProxyColony.makeArbitraryTransaction,
+ (_token, abi.encodeCall(ERC20.approve, (LIFI_ADDRESS, _amount)))
+ );
+ actions[1] = abi.encodeCall(ProxyColony.makeArbitraryTransaction, (LIFI_ADDRESS, _txdata));
+
+ bytes memory multicallData = abi.encodeWithSignature("multicall(bytes[])", actions);
+
+ IColony(address(this)).makeProxyArbitraryTransaction(
+ _chainId,
+ address(this),
+ multicallData
+ );
+ }
+ }
+ }
+
function getNonRewardPotsTotal(address _token) public view returns (uint256) {
- return nonRewardPotsTotal[_token];
+ return getNonRewardPotsTotal(block.chainid, _token);
+ }
+
+ function getNonRewardPotsTotal(uint256 _chainId, address _token) public view returns (uint256) {
+ if (_chainId == block.chainid) {
+ return nonRewardPotsTotal[_token];
+ } else {
+ return chainNonRewardPotsTotals[_chainId][_token];
+ }
+ }
+
+ function incrementNonRewardPotsTotal(
+ uint256 _chainId,
+ address _token,
+ uint256 _increment
+ ) internal {
+ if (_chainId == block.chainid) {
+ nonRewardPotsTotal[_token] += _increment;
+ } else {
+ chainNonRewardPotsTotals[_chainId][_token] += _increment;
+ }
+ }
+
+ function decrementNonRewardPotsTotal(
+ uint256 _chainId,
+ address _token,
+ uint256 _decrement
+ ) internal {
+ if (_chainId == block.chainid) {
+ nonRewardPotsTotal[_token] -= _decrement;
+ } else {
+ chainNonRewardPotsTotals[_chainId][_token] -= _decrement;
+ }
}
/// @notice For owners to update payouts with one token and many slots
@@ -199,7 +368,7 @@ contract ColonyFunding is
address _token,
uint256[] memory _amounts
) public stoppable expenditureDraft(_id) expenditureOnlyOwner(_id) {
- setExpenditurePayoutsInternal(_id, _slots, _token, _amounts);
+ setExpenditurePayoutsInternal(_id, _slots, block.chainid, _token, _amounts);
}
/// @notice For arbitrators to update payouts with one token and one slot
@@ -210,6 +379,26 @@ contract ColonyFunding is
uint256 _slot,
address _token,
uint256 _amount
+ ) public stoppable {
+ setExpenditurePayout(
+ _permissionDomainId,
+ _childSkillIndex,
+ _id,
+ _slot,
+ block.chainid,
+ _token,
+ _amount
+ );
+ }
+
+ function setExpenditurePayout(
+ uint256 _permissionDomainId,
+ uint256 _childSkillIndex,
+ uint256 _id,
+ uint256 _slot,
+ uint256 _chainId,
+ address _token,
+ uint256 _amount
)
public
stoppable
@@ -220,7 +409,7 @@ contract ColonyFunding is
slots[0] = _slot;
uint256[] memory amounts = new uint256[](1);
amounts[0] = _amount;
- setExpenditurePayoutsInternal(_id, slots, _token, amounts);
+ setExpenditurePayoutsInternal(_id, slots, _chainId, _token, amounts);
}
/// @notice For owners to update payouts with one token and one slot
@@ -234,15 +423,34 @@ contract ColonyFunding is
slots[0] = _slot;
uint256[] memory amounts = new uint256[](1);
amounts[0] = _amount;
- setExpenditurePayoutsInternal(_id, slots, _token, amounts);
+ setExpenditurePayoutsInternal(_id, slots, block.chainid, _token, amounts);
+ }
+
+ function setExpenditurePayout(
+ uint256 _id,
+ uint256 _slot,
+ uint256 _chainId,
+ address _token,
+ uint256 _amount
+ ) public stoppable expenditureDraft(_id) expenditureOnlyOwner(_id) {
+ uint256[] memory slots = new uint256[](1);
+ slots[0] = _slot;
+ uint256[] memory amounts = new uint256[](1);
+ amounts[0] = _amount;
+ setExpenditurePayoutsInternal(_id, slots, _chainId, _token, amounts);
}
int256 constant MAX_PAYOUT_MODIFIER = int256(WAD);
int256 constant MIN_PAYOUT_MODIFIER = -int256(WAD);
+ function claimExpenditurePayout(uint256 _id, uint256 _slot, address _token) public stoppable {
+ claimExpenditurePayout(_id, _slot, block.chainid, _token);
+ }
+
function claimExpenditurePayout(
uint256 _id,
uint256 _slot,
+ uint256 _chainId,
address _token
) public stoppable expenditureFinalized(_id) {
Expenditure storage expenditure = expenditures[_id];
@@ -258,25 +466,35 @@ contract ColonyFunding is
"colony-expenditure-cannot-claim"
);
- FundingPot storage fundingPot = fundingPots[expenditure.fundingPotId];
- assert(fundingPot.balance[_token] >= fundingPot.payouts[_token]);
+ uint256 fundingPotId = expenditure.fundingPotId;
+ assert(
+ getFundingPotBalance(fundingPotId, _chainId, _token) >=
+ getFundingPotPayout(fundingPotId, _chainId, _token)
+ );
- uint256 initialPayout = expenditureSlotPayouts[_id][_slot][_token];
- delete expenditureSlotPayouts[_id][_slot][_token];
+ uint256 repPayout;
+ uint256 tokenPayout;
- int256 payoutModifier = imin(
- imax(slot.payoutModifier, MIN_PAYOUT_MODIFIER),
- MAX_PAYOUT_MODIFIER
- );
- uint256 payoutScalar = uint256(payoutModifier + int256(WAD));
+ {
+ uint256 initialPayout = getExpenditureSlotPayout(_id, _slot, _chainId, _token);
+ setExpenditureSlotPayout(_id, _slot, _chainId, _token, 0);
- uint256 repPayout = wmul(initialPayout, payoutScalar);
- uint256 tokenPayout = min(initialPayout, repPayout);
- uint256 tokenSurplus = initialPayout - tokenPayout;
+ int256 payoutModifier = imin(
+ imax(slot.payoutModifier, MIN_PAYOUT_MODIFIER),
+ MAX_PAYOUT_MODIFIER
+ );
+ uint256 payoutScalar = uint256(payoutModifier + int256(WAD));
+ repPayout = wmul(initialPayout, payoutScalar);
+ tokenPayout = min(initialPayout, repPayout);
+ uint256 tokenSurplus = initialPayout - tokenPayout;
- // Deduct any surplus from the outstanding payouts (for payoutScalars < 1)
- if (tokenSurplus > 0) {
- fundingPot.payouts[_token] -= tokenSurplus;
+ // Deduct any surplus from the outstanding payouts (for payoutScalars < 1)
+
+ if (tokenSurplus > 0) {
+ // UNCOMMENT
+ uint256 oldFundingPotPayout = getFundingPotPayout(fundingPotId, _chainId, _token);
+ setFundingPotPayout(fundingPotId, _chainId, _token, oldFundingPotPayout - tokenSurplus);
+ }
}
// Process reputation updates if internal token
@@ -300,12 +518,13 @@ contract ColonyFunding is
// Finish the payout
uint256 payoutMinusFee = processPayout(
expenditure.fundingPotId,
+ _chainId,
_token,
tokenPayout,
slot.recipient
);
- emit PayoutClaimed(msgSender(), _id, _slot, _token, payoutMinusFee);
+ emit PayoutClaimed(msgSender(), _id, _slot, _chainId, _token, payoutMinusFee);
}
// View
@@ -315,11 +534,37 @@ contract ColonyFunding is
}
function getFundingPotBalance(uint256 _potId, address _token) public view returns (uint256) {
- return fundingPots[_potId].balance[_token];
+ return getFundingPotBalance(_potId, block.chainid, _token);
+ }
+
+ function getFundingPotBalance(
+ uint256 _potId,
+ uint256 _chainId,
+ address _token
+ ) public view returns (uint256) {
+ if (_chainId == block.chainid) {
+ return fundingPots[_potId].balance[_token];
+ }
+ return fundingPots[_potId].chainBalances[_chainId][_token];
+ }
+
+ function recordClaimedFundsFromBridge(
+ uint256 _chainId,
+ address _token,
+ uint256 _domainId,
+ uint256 _amount
+ ) public stoppable {
+ Domain storage d = domains[_domainId];
+ fundingPots[d.fundingPotId].chainBalances[_chainId][_token] += _amount;
+ // TODO: Reward pot?
+
+ incrementNonRewardPotsTotal(_chainId, _token, _amount);
+
+ emit ProxyColonyFundsClaimed(_chainId, _token, _amount);
}
function getFundingPotPayout(uint256 _potId, address _token) public view returns (uint256) {
- return fundingPots[_potId].payouts[_token];
+ return getFundingPotPayout(_potId, block.chainid, _token);
}
function getFundingPot(
@@ -366,19 +611,20 @@ contract ColonyFunding is
uint256 _fromPot,
uint256 _toPot,
uint256 _amount,
+ uint256 _chainId,
address _token
) internal {
FundingPot storage fromPot = fundingPots[_fromPot];
FundingPot storage toPot = fundingPots[_toPot];
- fromPot.balance[_token] -= _amount;
- toPot.balance[_token] += _amount;
+ decrementFundingPotBalance(_fromPot, _chainId, _token, _amount);
+ incrementFundingPotBalance(_toPot, _chainId, _token, _amount);
- if (_fromPot == 1) {
+ if (_fromPot == 1 && _chainId == block.chainid) {
// If we're moving from the root pot, then check we haven't dropped below what we need
// to cover any approvals that we've made.
require(
- fromPot.balance[_token] >= tokenApprovalTotals[_token],
+ getFundingPotBalance(_fromPot, block.chainid, _token) >= tokenApprovalTotals[_token],
"colony-funding-too-many-approvals"
);
}
@@ -388,42 +634,57 @@ contract ColonyFunding is
// unless the expenditure was cancelled
require(
expenditures[fromPot.associatedTypeId].status == ExpenditureStatus.Cancelled ||
- fromPot.balance[_token] >= fromPot.payouts[_token],
+ getFundingPotBalance(_fromPot, _chainId, _token) >=
+ getFundingPotPayout(_fromPot, _chainId, _token),
"colony-funding-expenditure-bad-state"
);
- uint256 fromPotPreviousAmount = fromPot.balance[_token] + _amount;
- updatePayoutsWeCannotMakeAfterPotChange(_fromPot, _token, fromPotPreviousAmount);
+ uint256 fromPotPreviousAmount = getFundingPotBalance(_fromPot, _chainId, _token) + _amount;
+ updatePayoutsWeCannotMakeAfterPotChange(_fromPot, _chainId, _token, fromPotPreviousAmount);
}
if (toPot.associatedType == FundingPotAssociatedType.Expenditure) {
- uint256 toPotPreviousAmount = toPot.balance[_token] - _amount;
- updatePayoutsWeCannotMakeAfterPotChange(_toPot, _token, toPotPreviousAmount);
+ uint256 toPotPreviousAmount = getFundingPotBalance(_toPot, _chainId, _token) - _amount;
+ updatePayoutsWeCannotMakeAfterPotChange(_toPot, _chainId, _token, toPotPreviousAmount);
}
if (_toPot == 0) {
- nonRewardPotsTotal[_token] -= _amount;
+ decrementNonRewardPotsTotal(_chainId, _token, _amount);
}
- emit ColonyFundsMovedBetweenFundingPots(msgSender(), _fromPot, _toPot, _amount, _token);
+ emit ColonyFundsMovedBetweenFundingPots(
+ msgSender(),
+ _fromPot,
+ _toPot,
+ _amount,
+ _chainId,
+ _token
+ );
}
function updatePayoutsWeCannotMakeAfterPotChange(
uint256 _fundingPotId,
+ uint256 _chainId,
address _token,
uint256 _prev
) internal {
FundingPot storage tokenPot = fundingPots[_fundingPotId];
- if (_prev >= tokenPot.payouts[_token]) {
+ if (_prev >= getFundingPotPayout(_fundingPotId, _chainId, _token)) {
// If the old amount in the pot was enough to pay for the budget
- if (tokenPot.balance[_token] < tokenPot.payouts[_token]) {
+ if (
+ getFundingPotBalance(_fundingPotId, _chainId, _token) <
+ getFundingPotPayout(_fundingPotId, _chainId, _token)
+ ) {
// And the new amount in the pot is not enough to pay for the budget...
tokenPot.payoutsWeCannotMake += 1; // Then this is a set of payouts we cannot make that we could before.
}
} else {
// If this 'else' is running, then the old amount in the pot could not pay for the budget
- if (tokenPot.balance[_token] >= tokenPot.payouts[_token]) {
+ if (
+ getFundingPotBalance(_fundingPotId, _chainId, _token) >=
+ getFundingPotPayout(_fundingPotId, _chainId, _token)
+ ) {
// And the new amount in the pot can pay for the budget
tokenPot.payoutsWeCannotMake -= 1; // Then this is a set of payouts we can make that we could not before.
}
@@ -432,20 +693,27 @@ contract ColonyFunding is
function updatePayoutsWeCannotMakeAfterBudgetChange(
uint256 _fundingPotId,
+ uint256 _chainId,
address _token,
uint256 _prev
) internal {
FundingPot storage tokenPot = fundingPots[_fundingPotId];
- if (tokenPot.balance[_token] >= _prev) {
+ if (getFundingPotBalance(_fundingPotId, _chainId, _token) >= _prev) {
// If the amount in the pot was enough to pay for the old budget...
- if (tokenPot.balance[_token] < tokenPot.payouts[_token]) {
+ if (
+ getFundingPotBalance(_fundingPotId, _chainId, _token) <
+ getFundingPotPayout(_fundingPotId, _chainId, _token)
+ ) {
// And the amount is not enough to pay for the new budget...
tokenPot.payoutsWeCannotMake += 1; // Then this is a set of payouts we cannot make that we could before.
}
} else {
// If this 'else' is running, then the amount in the pot was not enough to pay for the old budget
- if (tokenPot.balance[_token] >= tokenPot.payouts[_token]) {
+ if (
+ getFundingPotBalance(_fundingPotId, _chainId, _token) >=
+ getFundingPotPayout(_fundingPotId, _chainId, _token)
+ ) {
// And the amount is enough to pay for the new budget...
tokenPot.payoutsWeCannotMake -= 1; // Then this is a set of payouts we can make that we could not before.
}
@@ -455,6 +723,7 @@ contract ColonyFunding is
function setExpenditurePayoutsInternal(
uint256 _id,
uint256[] memory _slots,
+ uint256 _chainId,
address _token,
uint256[] memory _amounts
) internal {
@@ -463,22 +732,24 @@ contract ColonyFunding is
FundingPot storage fundingPot = fundingPots[expenditures[_id].fundingPotId];
assert(fundingPot.associatedType == FundingPotAssociatedType.Expenditure);
- uint256 previousTotal = fundingPot.payouts[_token];
- uint256 runningTotal = fundingPot.payouts[_token];
+ uint256 previousTotal = getFundingPotPayout(expenditures[_id].fundingPotId, _chainId, _token);
+ uint256 runningTotal = previousTotal;
for (uint256 i; i < _slots.length; i++) {
require(_amounts[i] <= MAX_PAYOUT, "colony-payout-too-large");
- uint256 currentPayout = expenditureSlotPayouts[_id][_slots[i]][_token];
-
- expenditureSlotPayouts[_id][_slots[i]][_token] = _amounts[i];
+ uint256 currentPayout = getExpenditureSlotPayout(_id, _slots[i], _chainId, _token);
+ setExpenditureSlotPayout(_id, _slots[i], _chainId, _token, _amounts[i]);
runningTotal = (runningTotal - currentPayout) + _amounts[i];
- emit ExpenditurePayoutSet(msgSender(), _id, _slots[i], _token, _amounts[i]);
+ emit ExpenditurePayoutSet(msgSender(), _id, _slots[i], _chainId, _token, _amounts[i]);
}
- fundingPot.payouts[_token] = runningTotal;
+ // fundingPot.payouts[_token] = runningTotal;
+ setFundingPotPayout(expenditures[_id].fundingPotId, _chainId, _token, runningTotal);
+
updatePayoutsWeCannotMakeAfterBudgetChange(
expenditures[_id].fundingPotId,
+ _chainId,
_token,
previousTotal
);
@@ -486,38 +757,65 @@ contract ColonyFunding is
function processPayout(
uint256 _fundingPotId,
+ uint256 _chainId,
address _token,
uint256 _payout,
address payable _user
) private returns (uint256) {
- refundDomain(_fundingPotId, _token);
+ refundDomain(_fundingPotId, _chainId, _token);
IColonyNetwork colonyNetworkContract = IColonyNetwork(colonyNetworkAddress);
address payable metaColonyAddress = colonyNetworkContract.getMetaColony();
- fundingPots[_fundingPotId].balance[_token] -= _payout;
- fundingPots[_fundingPotId].payouts[_token] -= _payout;
- nonRewardPotsTotal[_token] -= _payout;
+ decrementFundingPotBalance(_fundingPotId, _chainId, _token, _payout);
+ setFundingPotPayout(
+ _fundingPotId,
+ _chainId,
+ _token,
+ getFundingPotPayout(_fundingPotId, _chainId, _token) - _payout
+ );
+ decrementNonRewardPotsTotal(_chainId, _token, _payout);
uint256 fee = isOwnExtension(_user) ? 0 : calculateNetworkFeeForPayout(_payout);
uint256 payoutToUser = _payout - fee;
- if (_token == address(0x0)) {
- // Payout ether
- // Fee goes directly to Meta Colony
- _user.transfer(payoutToUser);
- metaColonyAddress.transfer(fee);
- } else {
- // Payout token
- // If it's a whitelisted token, it goes straight to the metaColony
- // If it's any other token, goes to the colonyNetwork contract first to be auctioned.
- ERC20Extended payoutToken = ERC20Extended(_token);
- assert(payoutToken.transfer(_user, payoutToUser));
- if (colonyNetworkContract.getPayoutWhitelist(_token)) {
- assert(payoutToken.transfer(metaColonyAddress, fee));
+ address feeReceiver = colonyNetworkContract.getPayoutWhitelist(_token)
+ ? metaColonyAddress
+ : colonyNetworkAddress;
+
+ if (_chainId == block.chainid) {
+ if (_token == address(0x0)) {
+ // Payout ether
+ // Fee goes directly to Meta Colony
+ _user.transfer(payoutToUser);
+ metaColonyAddress.transfer(fee);
} else {
- assert(payoutToken.transfer(colonyNetworkAddress, fee));
+ // Payout token
+ // If it's a whitelisted token, it goes straight to the metaColony
+ // If it's any other token, goes to the colonyNetwork contract first to be auctioned.
+ ERC20Extended payoutToken = ERC20Extended(_token);
+ assert(payoutToken.transfer(_user, payoutToUser));
+ assert(payoutToken.transfer(feeReceiver, fee));
}
+ } else {
+ bytes[] memory multicallArgs = new bytes[](2);
+
+ multicallArgs[0] = abi.encodeWithSignature(
+ "transferFromBridge(address,address,uint256)",
+ _token,
+ _user,
+ payoutToUser
+ );
+
+ multicallArgs[1] = abi.encodeWithSignature(
+ "transferFromBridge(address,address,uint256)",
+ _token,
+ feeReceiver,
+ fee
+ );
+
+ bytes memory multicallData = abi.encodeWithSignature("multicall(bytes[])", multicallArgs);
+ IColonyNetwork(colonyNetworkAddress).bridgeMessage(_chainId, multicallData);
}
// slither-disable-next-line reentrancy-unlimited-gas
@@ -526,17 +824,106 @@ contract ColonyFunding is
return payoutToUser;
}
- function refundDomain(uint256 _fundingPotId, address _token) private {
- FundingPot storage fundingPot = fundingPots[_fundingPotId];
- if (fundingPot.payouts[_token] < fundingPot.balance[_token]) {
+ function refundDomain(uint256 _fundingPotId, uint256 _chainId, address _token) private {
+ if (
+ getFundingPotPayout(_fundingPotId, _chainId, _token) <
+ getFundingPotBalance(_fundingPotId, _chainId, _token)
+ ) {
uint256 domainId = getDomainFromFundingPot(_fundingPotId);
- uint256 surplus = fundingPot.balance[_token] - fundingPot.payouts[_token];
+ uint256 surplus = getFundingPotBalance(_fundingPotId, _chainId, _token) -
+ getFundingPotPayout(_fundingPotId, _chainId, _token);
+
moveFundsBetweenPotsFunctionality(
_fundingPotId,
domains[domainId].fundingPotId,
surplus,
+ _chainId,
_token
);
}
}
+
+ function incrementFundingPotBalance(
+ uint256 _potId,
+ uint256 _chainId,
+ address _token,
+ uint256 _increment
+ ) internal {
+ if (_chainId == block.chainid) {
+ fundingPots[_potId].balance[_token] += _increment;
+ } else {
+ fundingPots[_potId].chainBalances[_chainId][_token] += _increment;
+ }
+ }
+
+ function decrementFundingPotBalance(
+ uint256 _potId,
+ uint256 _chainId,
+ address _token,
+ uint256 _decrement
+ ) internal {
+ if (_chainId == block.chainid) {
+ fundingPots[_potId].balance[_token] -= _decrement;
+ } else {
+ fundingPots[_potId].chainBalances[_chainId][_token] -= _decrement;
+ }
+ }
+
+ function getFundingPotPayout(
+ uint256 _potId,
+ uint256 _chainId,
+ address _token
+ ) internal view returns (uint256) {
+ if (_chainId == block.chainid) {
+ return fundingPots[_potId].payouts[_token];
+ }
+ return fundingPots[_potId].chainPayouts[_chainId][_token];
+ }
+
+ function setFundingPotPayout(
+ uint256 _potId,
+ uint256 _chainId,
+ address _token,
+ uint256 _newValue
+ ) internal {
+ if (_chainId == block.chainid) {
+ fundingPots[_potId].payouts[_token] = _newValue;
+ } else {
+ fundingPots[_potId].chainPayouts[_chainId][_token] = _newValue;
+ }
+ }
+
+ function getExpenditureSlotPayout(
+ uint256 _id,
+ uint256 _slot,
+ address _token
+ ) public view returns (uint256) {
+ return getExpenditureSlotPayout(_id, _slot, block.chainid, _token);
+ }
+
+ function getExpenditureSlotPayout(
+ uint256 _id,
+ uint256 _slot,
+ uint256 chainId,
+ address _token
+ ) public view returns (uint256) {
+ if (chainId == block.chainid) {
+ return expenditureSlotPayouts[_id][_slot][_token];
+ }
+ return expenditureSlotChainPayouts[_id][_slot][chainId][_token];
+ }
+
+ function setExpenditureSlotPayout(
+ uint256 _id,
+ uint256 _slot,
+ uint256 chainId,
+ address _token,
+ uint256 _newValue
+ ) internal {
+ if (chainId == block.chainid) {
+ expenditureSlotPayouts[_id][_slot][_token] = _newValue;
+ } else {
+ expenditureSlotChainPayouts[_id][_slot][chainId][_token] = _newValue;
+ }
+ }
}
diff --git a/contracts/colony/ColonyStorage.sol b/contracts/colony/ColonyStorage.sol
index 66571718f2..83ee502936 100755
--- a/contracts/colony/ColonyStorage.sol
+++ b/contracts/colony/ColonyStorage.sol
@@ -24,7 +24,6 @@ import { CommonStorage } from "./../common/CommonStorage.sol";
import { ERC20Extended } from "./../common/ERC20Extended.sol";
import { DomainRoles } from "./../common/DomainRoles.sol";
import { IColonyNetwork } from "./../colonyNetwork/IColonyNetwork.sol";
-import { ColonyNetworkDataTypes } from "./../colonyNetwork/ColonyNetworkDataTypes.sol";
import { ColonyExtension } from "./../extensions/ColonyExtension.sol";
import { PatriciaTreeProofs } from "./../patriciaTree/PatriciaTreeProofs.sol";
import { ColonyAuthority } from "./ColonyAuthority.sol";
@@ -33,7 +32,7 @@ import { ColonyDataTypes } from "./ColonyDataTypes.sol";
// ignore-file-swc-131
// ignore-file-swc-108
-contract ColonyStorage is ColonyDataTypes, ColonyNetworkDataTypes, DSMath, CommonStorage {
+contract ColonyStorage is ColonyDataTypes, DSMath, CommonStorage {
uint256 constant COLONY_NETWORK_SLOT = 6;
uint256 constant ROOT_LOCAL_SKILL_SLOT = 36;
@@ -117,6 +116,12 @@ contract ColonyStorage is ColonyDataTypes, ColonyNetworkDataTypes, DSMath, Commo
// Mapping of domainId to allowed amount of reputation received tokens could generate if paid out
mapping(uint256 => uint256) domainReputationApproval; // Storage slot 39
+ // Expenditure Id > Slot Id > Chain Id > Token Address > Amount
+ mapping(uint256 => mapping(uint256 => mapping(uint256 => mapping(address => uint256)))) expenditureSlotChainPayouts; // Storage slot 40
+
+ // Chain Id > Token Address > Amount
+ mapping(uint256 => mapping(address => uint256)) chainNonRewardPotsTotals; // Storage slot 41
+
// Constants
uint256 constant MAX_PAYOUT = 2 ** 128 - 1; // 340,282,366,920,938,463,463 WADs
@@ -251,7 +256,10 @@ contract ColonyStorage is ColonyDataTypes, ColonyNetworkDataTypes, DSMath, Commo
function isAuthorized(address src, uint256 domainId, bytes4 sig) internal view returns (bool) {
return
- (src == owner) || DomainRoles(address(authority)).canCall(src, domainId, address(this), sig);
+ // TODO: Is there a reason we didn't have (src==address(this)?)
+ (src == owner) ||
+ (src == address(this)) ||
+ DomainRoles(address(authority)).canCall(src, domainId, address(this), sig);
}
function isContract(address addr) internal returns (bool) {
diff --git a/contracts/colony/IColony.sol b/contracts/colony/IColony.sol
index d1af3f243f..d26f9d438b 100644
--- a/contracts/colony/IColony.sol
+++ b/contracts/colony/IColony.sol
@@ -61,6 +61,17 @@ interface IColony is IDSAuth, ColonyDataTypes, IRecovery, IBasicMetaTransaction,
bytes memory _action
) external returns (bool success);
+ /// @notice Execute arbitrary transactions on behalf of the Colony via a proxy colony on another chain
+ /// @dev If proxy colony not already deployed, will do nothing
+ /// @param chainId The chainId of the proxy colony
+ /// @param _destination Address to be targeted
+ /// @param _action Array of Bytes arrays encoding the function call
+ function makeProxyArbitraryTransaction(
+ uint256 chainId,
+ address _destination,
+ bytes memory _action
+ ) external;
+
/// @notice Execute arbitrary transactions on behalf of the Colony in series
/// @param _targets Array of addressed to be targeted
/// @param _actions Array of Bytes arrays encoding the function calls and arguments
@@ -556,6 +567,21 @@ interface IColony is IDSAuth, ColonyDataTypes, IRecovery, IBasicMetaTransaction,
uint256 _amount
) external;
+ /// @notice Set the token payout on an expenditure slot. Can only be called by expenditure owner.
+ /// @dev Can only be called while expenditure is in draft state.
+ /// @param _id Id of the expenditure
+ /// @param _slot Number of the slot
+ /// @param _chainId The chainId of the token
+ /// @param _token Address of the token, `0x0` value indicates Ether
+ /// @param _amount Payout amount
+ function setExpenditurePayout(
+ uint256 _id,
+ uint256 _slot,
+ uint256 _chainId,
+ address _token,
+ uint256 _amount
+ ) external;
+
/// @notice Set the token payouts in given expenditure slots. Can only be called by expenditure owner.
/// @dev Can only be called while expenditure is in draft state.
/// @param _id Id of the expenditure
@@ -569,11 +595,29 @@ interface IColony is IDSAuth, ColonyDataTypes, IRecovery, IBasicMetaTransaction,
uint256[] memory _amounts
) external;
+ /// @notice Set the token payout in a given expenditure slot. Can only be called by an Arbitration user.
+ /// @notice This function is deprecated and will be removed in a future version
+ /// @param _permissionDomainId The domainId in which I have the permission to take this action
+ /// @param _childSkillIndex The index that the `_domainId` is relative to `_permissionDomainId`
+ /// @param _id Id of the expenditure
+ /// @param _slot The slot to set the payout
+ /// @param _token Address of the token, `0x0` value indicates Ether
+ /// @param _amount Payout amount
+ function setExpenditurePayout(
+ uint256 _permissionDomainId,
+ uint256 _childSkillIndex,
+ uint256 _id,
+ uint256 _slot,
+ address _token,
+ uint256 _amount
+ ) external;
+
/// @notice Set the token payout in a given expenditure slot. Can only be called by an Arbitration user.
/// @param _permissionDomainId The domainId in which I have the permission to take this action
/// @param _childSkillIndex The index that the `_domainId` is relative to `_permissionDomainId`
/// @param _id Id of the expenditure
/// @param _slot The slot to set the payout
+ /// @param _chainId The chainId of the token
/// @param _token Address of the token, `0x0` value indicates Ether
/// @param _amount Payout amount
function setExpenditurePayout(
@@ -581,6 +625,7 @@ interface IColony is IDSAuth, ColonyDataTypes, IRecovery, IBasicMetaTransaction,
uint256 _childSkillIndex,
uint256 _id,
uint256 _slot,
+ uint256 _chainId,
address _token,
uint256 _amount
) external;
@@ -649,11 +694,24 @@ interface IColony is IDSAuth, ColonyDataTypes, IRecovery, IBasicMetaTransaction,
) external;
/// @notice Claim the payout for an expenditure slot. Here the network receives a fee from each payout.
+ /// @notice This function is deprecated and will be removed in a future version
/// @param _id Expenditure identifier
/// @param _slot Number of the slot
/// @param _token Address of the token, `0x0` value indicates Ether
function claimExpenditurePayout(uint256 _id, uint256 _slot, address _token) external;
+ /// @notice Claim the payout for an expenditure slot. Here the network receives a fee from each payout.
+ /// @param _id Expenditure identifier
+ /// @param _slot Number of the slot
+ /// @param _chainId The chainId of the token
+ /// @param _token Address of the token, `0x0` value indicates Ether
+ function claimExpenditurePayout(
+ uint256 _id,
+ uint256 _slot,
+ uint256 _chainId,
+ address _token
+ ) external;
+
/// @notice Get the number of expenditures in the colony.
/// @return count The expenditure count
function getExpenditureCount() external view returns (uint256 count);
@@ -774,6 +832,18 @@ interface IColony is IDSAuth, ColonyDataTypes, IRecovery, IBasicMetaTransaction,
/// @notice Get the `_token` balance of pot with id `_potId`.
/// @param _potId Id of the funding pot
+ /// @param _chainId The chainId of the token
+ /// @param _token Address of the token, `0x0` value indicates Ether
+ /// @return balance Funding pot supply balance
+ function getFundingPotBalance(
+ uint256 _potId,
+ uint256 _chainId,
+ address _token
+ ) external view returns (uint256 balance);
+
+ /// @notice Get the `_token` balance of pot with id `_potId`.
+ /// @notice Deprecated - use version with explicit chainId
+ /// @param _potId Id of the funding pot
/// @param _token Address of the token, `0x0` value indicates Ether
/// @return balance Funding pot supply balance
function getFundingPotBalance(
@@ -813,6 +883,31 @@ interface IColony is IDSAuth, ColonyDataTypes, IRecovery, IBasicMetaTransaction,
address _token
) external;
+ /// @notice Move a given amount: `_amount` of `_token` funds from funding pot with id `_fromPot` to one with id `_toPot`.
+ /// @param _permissionDomainId The domainId in which I have the permission to take this action
+ /// @param _childSkillIndex The child index in _permissionDomainId where I will be taking this action
+ /// @param _domainId The domain where I am taking this action, pointed to by _permissionDomainId and _childSkillIndex
+ /// @param _fromChildSkillIndex In the array of child skills for the skill associated with the domain pointed to by _permissionDomainId + _childSkillIndex,
+ /// the index of the skill associated with the domain that contains _fromPot
+ /// @param _toChildSkillIndex The same, but for the _toPot which the funds are being moved to
+ /// @param _fromPot Funding pot id providing the funds
+ /// @param _toPot Funding pot id receiving the funds
+ /// @param _amount Amount of funds
+ /// @param _chainId The chainId of the token
+ /// @param _token Address of the token, `0x0` value indicates Ether
+ function moveFundsBetweenPots(
+ uint256 _permissionDomainId,
+ uint256 _childSkillIndex,
+ uint256 _domainId,
+ uint256 _fromChildSkillIndex,
+ uint256 _toChildSkillIndex,
+ uint256 _fromPot,
+ uint256 _toPot,
+ uint256 _amount,
+ uint256 _chainId,
+ address _token
+ ) external;
+
/// @notice @deprecated
/// @notice Move a given amount: `_amount` of `_token` funds from funding pot with id `_fromPot` to one with id `_toPot`.
/// @param _permissionDomainId The domainId in which I have the permission to take this action
@@ -832,6 +927,13 @@ interface IColony is IDSAuth, ColonyDataTypes, IRecovery, IBasicMetaTransaction,
address _token
) external;
+ /// @notice Move any funds received by the colony in `_token` denomination to the top-level domain pot,
+ /// siphoning off a small amount to the reward pot. If called against a colony's own token, no fee is taken.
+ /// @param _chainId Chain id of the chain where the funds need to be claimed
+ /// @param _token Address of the token, `0x0` value indicates Ether
+ function claimColonyFunds(uint256 _chainId, address _token) external;
+
+ /// @notice Deprecated
/// @notice Move any funds received by the colony in `_token` denomination to the top-level domain pot,
/// siphoning off a small amount to the reward pot. If called against a colony's own token, no fee is taken.
/// @param _token Address of the token, `0x0` value indicates Ether
@@ -858,11 +960,60 @@ interface IColony is IDSAuth, ColonyDataTypes, IRecovery, IBasicMetaTransaction,
/// @return uint256 amount Amount of the token that the domain can receive
function getAllowedDomainReputationReceipt(uint256 _domainId) external view returns (uint256);
+ /// @notice Exchange funds between two tokens, potentially between chains
+ /// The tokens being swapped are held by a proxy contract
+ /// @param _permissionDomainId The domainId in which I have the permission to take this action
+ /// @param _childSkillIndex The child index in `_permissionDomainId` where we can find `_domainId`
+ /// @param _domainId Id of the domain
+ /// @param _txdata Transaction data for the exchange
+ /// @param _value Value of the transaction
+ /// @param _chainId The chainId of the token
+ /// @param _token Address of the token. If the native token is being swapped, can be anything and _amount should be 0.
+ /// @param _amount Amount of tokens to exchange
+ function exchangeTokensViaLiFi(
+ uint256 _permissionDomainId,
+ uint256 _childSkillIndex,
+ uint256 _domainId,
+ bytes memory _txdata,
+ uint256 _value,
+ uint256 _chainId,
+ address _token,
+ uint256 _amount
+ ) external;
+
+ /// @notice Used by the bridge to indicate that funds have been claimed on another chain.
+ /// @param _chainId Chain id of the chain where the funds were claimed
+ /// @param _token Address of the token, `0x0` value indicates Ether
+ /// @param _domainId Id of the domain where the funds were claimed
+ /// @param _amount Amount of funds claimed
+ function recordClaimedFundsFromBridge(
+ uint256 _chainId,
+ address _token,
+ uint256 _domainId,
+ uint256 _amount
+ ) external;
+
+ /// @notice Create a proxy colony on another chain
+ /// @param _destinationChainId Chain id of the destination chain
+ /// @param _salt The colony creation salt that was used on creation of the colony
+ function createProxyColony(uint256 _destinationChainId, bytes32 _salt) external;
+
+ /// @notice Deprecated. Use the version with explicit _chainId
/// @notice Get the total amount of tokens `_token` minus amount reserved to be paid to the reputation and token holders as rewards.
/// @param _token Address of the token, `0x0` value indicates Ether
/// @return amount Total amount of tokens in funding pots other than the rewards pot (id 0)
function getNonRewardPotsTotal(address _token) external view returns (uint256 amount);
+ /// @notice Get the total amount of tokens `_token` minus amount reserved to be paid to the reputation and token holders as rewards.
+ /// @param _chainId Chain id to query the total for
+ /// @param _token Address of the token, `0x0` value indicates Ether
+ /// @return amount Total amount of tokens in funding pots other than the rewards pot (id 0)
+ /// @dev NB This only returns totals that the colony knows about - unclaimed funds will not be included
+ function getNonRewardPotsTotal(
+ uint256 _chainId,
+ address _token
+ ) external view returns (uint256 amount);
+
/// @notice Allow the _approvee to obligate some amount of tokens as a stake.
/// @param _approvee Address of the account we are willing to let obligate us.
/// @param _domainId Domain in which we are willing to be obligated.
diff --git a/contracts/colony/IMetaColony.sol b/contracts/colony/IMetaColony.sol
index 67cc1768b3..077b3b5816 100644
--- a/contracts/colony/IMetaColony.sol
+++ b/contracts/colony/IMetaColony.sol
@@ -66,4 +66,9 @@ interface IMetaColony is IColony {
bytes32 newHash,
uint256 newNLeaves
) external;
+
+ /// @notice Call (a) function(s) on the proxyColonyNetwork on a different chain
+ /// @param _chainId The chainId of the chain the function is being called on
+ /// @param _actions The actions to be called
+ function multicallProxyNetwork(uint256 _chainId, bytes[] memory _actions) external;
}
diff --git a/contracts/colonyNetwork/ColonyNetwork.sol b/contracts/colonyNetwork/ColonyNetwork.sol
index 3ef6f23e30..87985b3a21 100644
--- a/contracts/colonyNetwork/ColonyNetwork.sol
+++ b/contracts/colonyNetwork/ColonyNetwork.sol
@@ -23,6 +23,7 @@ import { BasicMetaTransaction } from "./../common/BasicMetaTransaction.sol";
import { IReputationMiningCycle } from "./../reputationMiningCycle/IReputationMiningCycle.sol";
import { ColonyNetworkStorage } from "./ColonyNetworkStorage.sol";
import { Multicall } from "./../common/Multicall.sol";
+import { IColonyBridge } from "./../bridging/IColonyBridge.sol";
contract ColonyNetwork is BasicMetaTransaction, ColonyNetworkStorage, Multicall {
function isColony(address _colony) public view returns (bool) {
@@ -111,6 +112,23 @@ contract ColonyNetwork is BasicMetaTransaction, ColonyNetworkStorage, Multicall
emit ColonyNetworkInitialised(_resolver);
}
+ function bridgeMessage(uint256 _chainId, bytes memory _payload) public stoppable calledByColony {
+ require(
+ IColonyBridge(colonyBridgeAddress).sendMessage(_chainId, msg.sender, _payload),
+ "colony-network-bridge-message-failed"
+ );
+ }
+
+ function bridgeMessageToNetwork(
+ uint256 _chainId,
+ bytes memory _payload
+ ) public stoppable calledByMetaColony {
+ require(
+ IColonyBridge(colonyBridgeAddress).sendMessage(_chainId, address(this), _payload),
+ "colony-network-bridge-message-failed"
+ );
+ }
+
function getColony(uint256 _id) public view returns (address) {
return colonies[_id];
}
diff --git a/contracts/colonyNetwork/ColonyNetworkDataTypes.sol b/contracts/colonyNetwork/ColonyNetworkDataTypes.sol
index 3f4c3f0e68..dc15aacbdf 100755
--- a/contracts/colonyNetwork/ColonyNetworkDataTypes.sol
+++ b/contracts/colonyNetwork/ColonyNetworkDataTypes.sol
@@ -18,8 +18,10 @@
pragma solidity 0.8.28;
+import { CommonDataTypes } from "./../common/CommonDataTypes.sol";
+
// prettier-ignore
-interface ColonyNetworkDataTypes {
+interface ColonyNetworkDataTypes is CommonDataTypes{
/// @notice Event logged when the colony network is intialised. This is only ever emitted once in a network's lifetime
/// @param resolver The Resolver contract address used by the Colony version 1
event ColonyNetworkInitialised(address resolver);
@@ -67,19 +69,6 @@ interface ColonyNetworkDataTypes {
/// @param parentSkillId The id of the parent skill under which this new skill is added
event SkillAdded(uint256 skillId, uint256 parentSkillId);
- /// @notice Event logged when bridging of a skill creation did not succeed.
- /// @param skillId The skillId that failed to bridge
- event SkillCreationStored(uint256 skillId);
-
- /// @notice Event logged when a skill is received from a bridge, but can't yet be
- /// added to the skill tree.
- /// @param skillId The skillId of the skill that was bridged
- event SkillStoredFromBridge(uint256 skillId);
-
- /// @notice Event logged when a skill is successfully added from a bridge.
- /// @param skillId The skillId of the skill that was bridged
- event SkillAddedFromBridge(uint256 skillId);
-
/// @notice Event logged when a new auction is created and started
/// @dev Emitted from `IColonyNetwork.startTokenAuction` function
/// @param auction Address of the created auction contract
@@ -174,33 +163,11 @@ interface ColonyNetworkDataTypes {
/// @param count The number of the reputation update trying to be bridged in that colony
event ReputationUpdateSentToBridge(address colony, uint256 count);
- /// @notice Event logged when a reputation update is received from a bridge, but can't be
- /// added to the reputation update log due to being bridged out of order or the skill not existing.
- /// @param chainId The chainId of the chain the bridge is associated with
- /// @param colony The address of the colony where reputation is being emitted
- /// @param updateNumber The number of the reputation update bridged in that colony
- event ReputationUpdateStoredFromBridge(uint256 chainId, address colony, uint256 updateNumber);
-
- /// @notice Event logged when a reputation update is successfully bridged.
- /// @param chainId The chainId of the chain the bridge is associated with
- /// @param colony The address of the colony where reputation is being emitted
- /// @param updateNumber The number of the reputation update bridged in that colony
- event ReputationUpdateAddedFromBridge(uint256 chainId, address colony, uint256 updateNumber);
-
- struct Skill {
- // total number of parent skills
- uint128 nParents;
- // total number of child skills
- uint128 nChildren;
- // array of `skill_id`s of parent skills starting from the 1st to `n`th, where `n` is an integer power of two larger than or equal to 1
- uint256[] parents;
- // array of `skill_id`s of all child skills
- uint256[] children;
- // `true` for a global skill reused across colonies or `false` for a skill mapped to a single colony's domain
- bool DEPRECATED_globalSkill;
- // `true` for a skill that is deprecated NB: deprecation is now stored locally on colonies
- bool DEPRECATED_deprecated;
- }
+ /// @notice Event emitted when a proxy colony deployment is requested
+ /// @param colony The address of the colony that has requested the proxy deployment
+ /// @param destinationChainId The chain ID of the destination chain
+ /// @param salt The salt used to generate the proxy address
+ event ProxyColonyRequested(address colony, uint256 destinationChainId, bytes32 salt);
struct ENSRecord {
address addr;
diff --git a/contracts/colonyNetwork/ColonyNetworkDeployer.sol b/contracts/colonyNetwork/ColonyNetworkDeployer.sol
index 2051ce8da5..e0d7446193 100644
--- a/contracts/colonyNetwork/ColonyNetworkDeployer.sol
+++ b/contracts/colonyNetwork/ColonyNetworkDeployer.sol
@@ -30,10 +30,9 @@ import { ICreateX } from "./../../lib/createx/src/ICreateX.sol";
import { EtherRouterCreate3 } from "./../common/EtherRouterCreate3.sol";
import { IColonyBridge } from "./../bridging/IColonyBridge.sol";
import { DomainTokenReceiver } from "./../common/DomainTokenReceiver.sol";
+import { DomainReceiverManagement } from "./../common/DomainReceiverManagement.sol";
-contract ColonyNetworkDeployer is ColonyNetworkStorage {
- address constant CREATEX_ADDRESS = 0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed;
-
+contract ColonyNetworkDeployer is ColonyNetworkStorage, DomainReceiverManagement {
function createMetaColony(address _tokenAddress) public stoppable auth {
require(metaColony == address(0x0), "colony-meta-colony-exists-already");
@@ -132,6 +131,24 @@ contract ColonyNetworkDeployer is ColonyNetworkStorage {
return (address(token), colonyAddress);
}
+ function createProxyColony(
+ uint256 _destinationChainId,
+ bytes32 _salt
+ ) public stoppable calledByColony {
+ bytes32 guardedSalt = keccak256(abi.encode(bytes32(uint256(uint160(address(this)))), _salt));
+ require(
+ msgSender() == ICreateX(CREATEX_ADDRESS).computeCreate3Address(guardedSalt),
+ "colony-network-wrong-salt"
+ );
+
+ bytes memory payload = abi.encodeWithSignature("createProxyColonyFromBridge(bytes32)", _salt);
+ require(
+ IColonyBridge(colonyBridgeAddress).sendMessage(_destinationChainId, address(this), payload),
+ "colony-network-create-proxy-colony-failed"
+ );
+ emit ProxyColonyRequested(msgSender(), _destinationChainId, _salt);
+ }
+
/**
* @dev Generates pseudo-randomly a salt value using a diverse selection of block and
* transaction properties.
@@ -182,75 +199,17 @@ contract ColonyNetworkDeployer is ColonyNetworkStorage {
domainReceiverResolverAddress = _resolver;
}
- function getDomainTokenReceiverResolver() public view returns (address) {
+ function getDomainTokenReceiverResolver() public view override stoppable returns (address) {
return domainReceiverResolverAddress;
}
- function idempotentDeployDomainTokenReceiver(
- uint256 _domainId
- ) public stoppable calledByColony returns (address domainTokenReceiverAddress) {
- // Calculate the address the domain should be receiving funds at
- domainTokenReceiverAddress = getDomainTokenReceiverAddress(msgSender(), _domainId);
-
- if (!isContract(domainTokenReceiverAddress)) {
- // Then deploy the contract
- bytes32 salt = getDomainTokenReceiverDeploySalt(msgSender(), _domainId);
- address deployedAddress = deployEtherRouterViaCreateX(salt);
- require(
- deployedAddress == domainTokenReceiverAddress,
- "colony-network-domain-receiver-deploy-wrong-address"
- );
-
- // Set up the deployed contract
- EtherRouter(payable(domainTokenReceiverAddress)).setResolver(domainReceiverResolverAddress);
- DomainTokenReceiver(domainTokenReceiverAddress).setColony(msgSender());
- } else {
- // Contract is deployed, check it's got the right resolver
- try EtherRouter(payable(domainTokenReceiverAddress)).resolver() returns (Resolver resolver) {
- if (address(resolver) != domainReceiverResolverAddress) {
- EtherRouter(payable(domainTokenReceiverAddress)).setResolver(
- domainReceiverResolverAddress
- );
- }
- } catch {
- revert("colony-network-domain-receiver-not-etherrouter");
- }
- }
-
- return domainTokenReceiverAddress;
- }
-
- function getDomainTokenReceiverAddress(
- address _colony,
- uint256 _domainId
- ) public view returns (address) {
- bytes32 salt = getDomainTokenReceiverDeploySalt(_colony, _domainId);
-
- // To get the correct address, we have to mimic the _guard functionality of CreateX
- bytes32 guardedSalt = keccak256(abi.encode(bytes32(uint256(uint160(address(this)))), salt));
- return ICreateX(CREATEX_ADDRESS).computeCreate3Address(guardedSalt);
+ function msgSenderIsColony() internal view override returns (bool) {
+ require(_isColony[msgSender()], "colony-caller-must-be-colony");
+ return msgSender() == msg.sender;
}
- function getDomainTokenReceiverDeploySalt(
- address _colony,
- uint256 _domainId
- ) internal view returns (bytes32) {
- // Calculate the address the domain should be receiving funds at
- // We only want Colony Networks to be able to deploy to the same address,
- // so we use the permissioned deploy protection feature of CreateX, and set
- // the first 160 bits of the salt to the address of this contract.
-
- bytes32 salt = bytes32(uint256(uint160(address(this)))) << 96;
-
- bytes32 additionalSalt = keccak256(abi.encode(_colony, _domainId));
- // We use the first 88 bits of the additional salt, which is a function of the colony and domainId,
- // to add entropy in the last 88 bits of the salt
- salt = salt | (additionalSalt >> 168);
- // We have set the first 160 bits, and the last 88 bits of the salt
- // Note that this leaves byte 21 of the salt as zero (0x00), which disables cross-chain
- // redeployment protection in createX.
- // This is intentional, as we want to allow the same receiver to be deployed on different chains
- return salt;
+ function isStopped() internal view override returns (bool) {
+ return recoveryMode;
}
function deployColony(address _tokenAddress, uint256 _version) internal returns (address) {
@@ -284,9 +243,6 @@ contract ColonyNetworkDeployer is ColonyNetworkStorage {
// Initialise the domain tree with defaults by just incrementing the skillCount
skillCount += 1;
- // If we're not mining chain, then bridge the skill
- IColonyNetwork(address(this)).bridgeSkillIfNotMiningChain(skillCount);
-
colony.initialiseColony(address(this), _tokenAddress);
emit ColonyAdded(colonyCount, address(etherRouter), _tokenAddress);
@@ -310,26 +266,4 @@ contract ColonyNetworkDeployer is ColonyNetworkStorage {
DSAuth dsauth = DSAuth(_colonyAddress);
dsauth.setOwner(address(0x0));
}
-
- function deployEtherRouterViaCreateX(bytes32 _salt) internal returns (address) {
- EtherRouter etherRouter = EtherRouter(
- payable(
- ICreateX(CREATEX_ADDRESS).deployCreate3AndInit(
- _salt,
- type(EtherRouterCreate3).creationCode,
- abi.encodeWithSignature("setOwner(address)", (address(this))),
- ICreateX.Values(0, 0)
- )
- )
- );
- return address(etherRouter);
- }
-
- function isContract(address addr) internal view returns (bool) {
- uint256 size;
- assembly {
- size := extcodesize(addr)
- }
- return size > 0;
- }
}
diff --git a/contracts/colonyNetwork/ColonyNetworkMining.sol b/contracts/colonyNetwork/ColonyNetworkMining.sol
index cbb154903d..d31ea0c915 100644
--- a/contracts/colonyNetwork/ColonyNetworkMining.sol
+++ b/contracts/colonyNetwork/ColonyNetworkMining.sol
@@ -41,7 +41,7 @@ contract ColonyNetworkMining is ColonyNetworkStorage {
_;
}
- function setMiningDelegate(address _delegate, bool _allowed) public onlyMiningChain stoppable {
+ function setMiningDelegate(address _delegate, bool _allowed) public stoppable miningInitialised {
if (miningDelegators[_delegate] != address(0x00)) {
require(
miningDelegators[_delegate] == msgSender(),
@@ -69,7 +69,7 @@ contract ColonyNetworkMining is ColonyNetworkStorage {
address _colony,
uint128 _nUpdates,
uint128 _nPreviousUpdates
- ) public onlyMiningChain recovery auth {
+ ) public recovery auth miningInitialised {
replacementReputationUpdateLogsExist[_reputationMiningCycle] = true;
replacementReputationUpdateLog[_reputationMiningCycle][_id] = ReputationLogEntry(
@@ -98,45 +98,11 @@ contract ColonyNetworkMining is ColonyNetworkStorage {
// Well this is a weird hack to need
function newAddressArray() internal pure returns (address[] memory) {}
- function setReputationRootHashFromBridge(
- bytes32 _newHash,
- uint256 _newNLeaves,
- uint256 _nonce
- ) public stoppable onlyNotMiningChain onlyColonyBridge {
- require(
- _nonce >= bridgeCurrentRootHashNonces[block.chainid],
- "colony-mining-bridge-invalid-nonce"
- );
- bridgeCurrentRootHashNonces[block.chainid] = _nonce;
- reputationRootHash = _newHash;
- reputationRootHashNLeaves = _newNLeaves;
-
- emit ReputationRootHashSet(_newHash, _newNLeaves, newAddressArray(), 0);
- }
-
- function bridgeCurrentRootHash(uint256 _chainId) public onlyMiningChain stoppable {
- require(colonyBridgeAddress != address(0x0), "colony-network-bridge-not-set");
-
- bridgeCurrentRootHashNonces[_chainId] += 1;
-
- bytes memory payload = abi.encodeWithSignature(
- "setReputationRootHashFromBridge(bytes32,uint256,uint256)",
- reputationRootHash,
- reputationRootHashNLeaves,
- bridgeCurrentRootHashNonces[_chainId]
- );
-
- // slither-disable-next-line unchecked-lowlevel
- bool success = IColonyBridge(colonyBridgeAddress).sendMessage(_chainId, payload);
- // We require success so estimation calls can tell us if bridging is going to work
- require(success, "colony-mining-bridge-call-failed");
- }
-
function setReputationRootHash(
bytes32 newHash,
uint256 newNLeaves,
address[] memory stakers
- ) public onlyMiningChain stoppable onlyReputationMiningCycle {
+ ) public stoppable miningInitialised onlyReputationMiningCycle {
reputationRootHash = newHash;
reputationRootHashNLeaves = newNLeaves;
// Reward stakers
@@ -197,7 +163,7 @@ contract ColonyNetworkMining is ColonyNetworkStorage {
}
// slither-disable-next-line reentrancy-no-eth
- function startNextCycle() public onlyMiningChain stoppable {
+ function startNextCycle() public stoppable miningInitialised {
address clnyToken = IMetaColony(metaColony).getToken();
require(clnyToken != address(0x0), "colony-reputation-mining-clny-token-invalid-address");
require(activeReputationMiningCycle == address(0x0), "colony-reputation-mining-still-active");
@@ -297,7 +263,7 @@ contract ColonyNetworkMining is ColonyNetworkStorage {
function punishStakers(
address[] memory _stakers,
uint256 _amount
- ) public onlyMiningChain stoppable onlyReputationMiningCycle {
+ ) public stoppable miningInitialised onlyReputationMiningCycle {
address clnyToken = IMetaColony(metaColony).getToken();
uint256 lostStake;
// Passing an array so that we don't incur the EtherRouter overhead for each staker if we looped over
@@ -319,19 +285,19 @@ contract ColonyNetworkMining is ColonyNetworkStorage {
function reward(
address _recipient,
uint256 _amount
- ) public onlyMiningChain stoppable onlyReputationMiningCycle {
+ ) public stoppable miningInitialised onlyReputationMiningCycle {
// TODO: Gain rep?
pendingMiningRewards[_recipient] += _amount;
}
- function claimMiningReward(address _recipient) public onlyMiningChain stoppable {
+ function claimMiningReward(address _recipient) public miningInitialised stoppable {
address clnyToken = IMetaColony(metaColony).getToken();
uint256 amount = pendingMiningRewards[_recipient];
pendingMiningRewards[_recipient] = 0;
ITokenLocking(tokenLocking).transfer(clnyToken, amount, _recipient, true);
}
- function stakeForMining(uint256 _amount) public onlyMiningChainOrDuringSetup stoppable {
+ function stakeForMining(uint256 _amount) public stoppable miningInitialisedOrDuringSetup {
address clnyToken = IMetaColony(metaColony).getToken();
ITokenLocking(tokenLocking).approveStake(msgSender(), _amount, clnyToken);
@@ -346,7 +312,7 @@ contract ColonyNetworkMining is ColonyNetworkStorage {
miningStakes[msgSender()].amount += _amount;
}
- function unstakeForMining(uint256 _amount) public onlyMiningChain stoppable {
+ function unstakeForMining(uint256 _amount) public stoppable miningInitialised {
address clnyToken = IMetaColony(metaColony).getToken();
// Prevent those involved in a mining cycle withdrawing stake during the mining process.
require(
@@ -363,7 +329,7 @@ contract ColonyNetworkMining is ColonyNetworkStorage {
function burnUnneededRewards(
uint256 _amount
- ) public onlyMiningChain stoppable onlyReputationMiningCycle {
+ ) public stoppable miningInitialised onlyReputationMiningCycle {
// If there are no rewards to burn, no need to do anything
if (_amount == 0) {
return;
@@ -380,7 +346,7 @@ contract ColonyNetworkMining is ColonyNetworkStorage {
function setReputationMiningCycleReward(
uint256 _amount
- ) public onlyMiningChain stoppable calledByMetaColony {
+ ) public stoppable miningInitialised calledByMetaColony {
totalMinerRewardPerCycle = _amount;
emit ReputationMiningRewardSet(_amount);
@@ -414,7 +380,7 @@ contract ColonyNetworkMining is ColonyNetworkStorage {
function setMiningResolver(
address _miningResolver
- ) public stoppable onlyMiningChainOrDuringSetup auth {
+ ) public stoppable auth miningInitialisedOrDuringSetup {
require(_miningResolver != address(0x0), "colony-mining-resolver-cannot-be-zero");
miningCycleResolver = _miningResolver;
diff --git a/contracts/colonyNetwork/ColonyNetworkSkills.sol b/contracts/colonyNetwork/ColonyNetworkSkills.sol
index 4133da000f..18ece72485 100644
--- a/contracts/colonyNetwork/ColonyNetworkSkills.sol
+++ b/contracts/colonyNetwork/ColonyNetworkSkills.sol
@@ -22,9 +22,8 @@ import "./../reputationMiningCycle/IReputationMiningCycle.sol";
import "./../common/Multicall.sol";
import "./ColonyNetworkStorage.sol";
import { IColonyBridge } from "./../bridging/IColonyBridge.sol";
-import { CallWithGuards } from "../common/CallWithGuards.sol";
-contract ColonyNetworkSkills is ColonyNetworkStorage, Multicall, CallWithGuards {
+contract ColonyNetworkSkills is ColonyNetworkStorage, Multicall {
// Skills
function addSkill(
@@ -33,8 +32,6 @@ contract ColonyNetworkSkills is ColonyNetworkStorage, Multicall, CallWithGuards
skillCount += 1;
addSkillToChainTree(_parentSkillId, skillCount);
- bridgeSkillIfNotMiningChain(skillCount);
-
return skillCount;
}
@@ -44,8 +41,6 @@ contract ColonyNetworkSkills is ColonyNetworkStorage, Multicall, CallWithGuards
function initialiseRootLocalSkill() public stoppable calledByColony returns (uint256) {
skillCount += 1;
- // If we're not mining chain, then bridge the skill
- bridgeSkillIfNotMiningChain(skillCount);
return skillCount;
}
@@ -62,11 +57,17 @@ contract ColonyNetworkSkills is ColonyNetworkStorage, Multicall, CallWithGuards
return;
}
- if (isMiningChain()) {
- appendReputationUpdateLogInternal(_user, _amount, _skillId, msgSender());
- } else {
- bridgeReputationUpdateLog(_user, _amount, _skillId);
- }
+ uint128 nParents = skills[_skillId].nParents;
+ // We only update child skill reputation if the update is negative, otherwise just set nChildren to 0 to save gas
+ uint128 nChildren = (_amount < 0) ? skills[_skillId].nChildren : 0;
+ IReputationMiningCycle(inactiveReputationMiningCycle).appendReputationUpdateLog(
+ _user,
+ _amount,
+ _skillId,
+ msgSender(),
+ nParents,
+ nChildren
+ );
}
// Bridging (sending)
@@ -81,193 +82,6 @@ contract ColonyNetworkSkills is ColonyNetworkStorage, Multicall, CallWithGuards
emit BridgeSet(_bridgeAddress);
}
- function bridgeSkillIfNotMiningChain(uint256 _skillId) public stoppable skillExists(_skillId) {
- if (isMiningChain()) {
- return;
- }
- // Build the transaction we're going to send to the bridge to register the
- // creation of this skill on the home chain
- uint256 parentSkillId = skills[_skillId].parents.length == 0
- ? (toRootSkillId(block.chainid))
- : skills[_skillId].parents[0];
-
- bytes memory payload = abi.encodeWithSignature(
- "addSkillFromBridge(uint256,uint256)",
- parentSkillId,
- _skillId
- );
-
- // Send bridge transaction
- bool success = callThroughBridgeWithGuards(payload);
-
- if (!success) {
- // Skill creation is implicitly stored by the fact that skillCount has been incremented
- emit SkillCreationStored(_skillId);
- }
- }
-
- function bridgePendingReputationUpdate(
- address _colony,
- uint256 _updateNumber
- ) public stoppable onlyNotMiningChain {
- require(colonyBridgeAddress != address(0x0), "colony-network-foreign-bridge-not-set");
- require(
- pendingReputationUpdates[block.chainid][_colony][_updateNumber - 1].colony == address(0x00),
- "colony-network-not-next-pending-update"
- );
-
- PendingReputationUpdate storage pendingUpdate = pendingReputationUpdates[block.chainid][
- _colony
- ][_updateNumber];
- require(pendingUpdate.colony != address(0x00), "colony-network-update-does-not-exist");
-
- int256 updateAmount = decayReputation(pendingUpdate.amount, pendingUpdate.timestamp);
-
- // Build the transaction we're going to send to the bridge
- bytes memory payload = abi.encodeWithSignature(
- "addReputationUpdateLogFromBridge(address,address,int256,uint256,uint256)",
- pendingUpdate.colony,
- pendingUpdate.user,
- updateAmount,
- pendingUpdate.skillId,
- _updateNumber
- );
-
- delete pendingReputationUpdates[block.chainid][_colony][_updateNumber];
-
- bool success = callThroughBridgeWithGuards(payload);
-
- require(success, "colony-network-bridging-tx-unsuccessful");
-
- emit ReputationUpdateSentToBridge(_colony, _updateNumber);
- }
-
- // Bridging (receiving)
-
- function addSkillFromBridge(
- uint256 _parentSkillId,
- uint256 _skillId
- ) public always onlyMiningChain onlyColonyBridge {
- uint256 bridgeChainId = toChainId(_skillId);
- if (networkSkillCounts[bridgeChainId] == 0) {
- // Initialise the skill count to match the foreign chain
- networkSkillCounts[bridgeChainId] = toRootSkillId(bridgeChainId);
- }
-
- require(networkSkillCounts[bridgeChainId] < _skillId, "colony-network-skill-already-added");
-
- // Check skill count - if not next, then store for later.
- if (networkSkillCounts[bridgeChainId] + 1 == _skillId) {
- addSkillToChainTree(_parentSkillId, _skillId);
- networkSkillCounts[bridgeChainId] += 1;
-
- emit SkillAddedFromBridge(_skillId);
- } else {
- require(
- pendingSkillAdditions[bridgeChainId][_skillId] == 0,
- "colony-network-skill-already-pending"
- );
-
- pendingSkillAdditions[bridgeChainId][_skillId] = _parentSkillId;
-
- emit SkillStoredFromBridge(_skillId);
- }
- }
-
- function addReputationUpdateLogFromBridge(
- address _colony,
- address _user,
- int256 _amount,
- uint256 _skillId,
- uint256 _updateNumber
- ) public stoppable onlyMiningChain onlyColonyBridge {
- uint256 bridgeChainId = toChainId(_skillId);
-
- require(
- reputationUpdateCount[bridgeChainId][_colony] < _updateNumber,
- "colony-network-update-already-added"
- );
-
- // If next expected update, add to log
- if (
- reputationUpdateCount[bridgeChainId][_colony] + 1 == _updateNumber && // It's the next reputation update for this colony
- networkSkillCounts[bridgeChainId] >= _skillId // Skill has been bridged
- ) {
- reputationUpdateCount[bridgeChainId][_colony] += 1;
- appendReputationUpdateLogInternal(_user, _amount, _skillId, _colony);
-
- emit ReputationUpdateAddedFromBridge(bridgeChainId, _colony, _updateNumber);
- } else {
- // Not next update, store for later
- require(
- pendingReputationUpdates[bridgeChainId][_colony][_updateNumber].timestamp == 0,
- "colony-network-update-already-pending"
- );
- pendingReputationUpdates[bridgeChainId][_colony][_updateNumber] = PendingReputationUpdate(
- _user,
- _amount,
- _skillId,
- _colony,
- block.timestamp
- );
-
- emit ReputationUpdateStoredFromBridge(bridgeChainId, _colony, _updateNumber);
- }
- }
-
- function addPendingSkill(uint256 _skillId) public always onlyMiningChain {
- uint256 bridgeChainId = toChainId(_skillId);
-
- // Require that specified skill is next
- // Note this also implicitly checks that the chainId prefix of the skill is correct
- require(
- networkSkillCounts[bridgeChainId] + 1 == _skillId,
- "colony-network-not-next-bridged-skill"
- );
-
- uint256 parentSkillId = pendingSkillAdditions[bridgeChainId][_skillId];
- require(parentSkillId != 0, "colony-network-no-such-bridged-skill");
- addSkillToChainTree(parentSkillId, _skillId);
- networkSkillCounts[bridgeChainId] += 1;
-
- // Delete the pending addition
- delete pendingSkillAdditions[bridgeChainId][_skillId];
-
- emit SkillAddedFromBridge(_skillId);
- }
-
- function addPendingReputationUpdate(
- uint256 _chainId,
- address _colony
- ) public stoppable onlyMiningChain {
- uint256 mostRecentUpdateNumber = reputationUpdateCount[_chainId][_colony];
- assert(
- pendingReputationUpdates[_chainId][_colony][mostRecentUpdateNumber].colony == address(0x00)
- );
-
- PendingReputationUpdate storage pendingUpdate = pendingReputationUpdates[_chainId][_colony][
- mostRecentUpdateNumber + 1
- ];
- require(pendingUpdate.colony != address(0x00), "colony-network-next-update-does-not-exist");
-
- // Skill creation must have been bridged
- require(
- networkSkillCounts[toChainId(pendingUpdate.skillId)] >= pendingUpdate.skillId,
- "colony-network-invalid-skill-id"
- );
-
- reputationUpdateCount[_chainId][_colony] += 1;
- address user = pendingUpdate.user;
- uint256 skillId = pendingUpdate.skillId;
- int256 updateAmount = decayReputation(pendingUpdate.amount, pendingUpdate.timestamp);
-
- delete pendingReputationUpdates[_chainId][_colony][mostRecentUpdateNumber + 1];
-
- appendReputationUpdateLogInternal(user, updateAmount, skillId, _colony);
-
- emit ReputationUpdateAddedFromBridge(_chainId, _colony, mostRecentUpdateNumber + 1);
- }
-
// View
function getParentSkillId(
@@ -297,46 +111,9 @@ contract ColonyNetworkSkills is ColonyNetworkStorage, Multicall, CallWithGuards
return colonyBridgeAddress;
}
- function getBridgedSkillCounts(uint256 _chainId) public view returns (uint256) {
- if (networkSkillCounts[_chainId] == 0) {
- return toRootSkillId(_chainId);
- }
- return networkSkillCounts[_chainId];
- }
-
- function getBridgedReputationUpdateCount(
- uint256 _chainId,
- address _colony
- ) public view returns (uint256) {
- return reputationUpdateCount[_chainId][_colony];
- }
-
- function getPendingSkillAddition(
- uint256 _chainId,
- uint256 _skillCount
- ) public view returns (uint256) {
- return pendingSkillAdditions[_chainId][_skillCount];
- }
-
- function getPendingReputationUpdate(
- uint256 _chainId,
- address _colony,
- uint256 _updateNumber
- ) public view onlyMiningChain returns (PendingReputationUpdate memory) {
- return pendingReputationUpdates[_chainId][_colony][_updateNumber];
- }
-
// Internal
function addSkillToChainTree(uint256 _parentSkillId, uint256 _skillId) private {
- // This indicates a new root local skill bridged from another chain, i.e. 0x{chainId}{0}
- // We don't do anything to the tree in this scenario, other than incrementing the skill count,
- // which should be/is done where this function is called.
- // (this mirrors the behaviour of not calling addSkill() in initialiseRootLocalSkill)
- if (_parentSkillId != 0 && _parentSkillId << 128 == 0) {
- return;
- }
-
require(_parentSkillId > 0, "colony-network-invalid-parent-skill");
Skill storage parentSkill = skills[_parentSkillId];
@@ -398,111 +175,4 @@ contract ColonyNetworkSkills is ColonyNetworkStorage, Multicall, CallWithGuards
}
}
}
-
- function appendReputationUpdateLogInternal(
- address _user,
- int256 _amount,
- uint256 _skillId,
- address _colony
- ) internal {
- uint128 nParents = skills[_skillId].nParents;
- // We only update child skill reputation if the update is negative, otherwise just set nChildren to 0 to save gas
- uint128 nChildren = (_amount < 0) ? skills[_skillId].nChildren : 0;
- IReputationMiningCycle(inactiveReputationMiningCycle).appendReputationUpdateLog(
- _user,
- _amount,
- _skillId,
- _colony,
- nParents,
- nChildren
- );
- }
-
- function bridgeReputationUpdateLog(address _user, int256 _amount, uint256 _skillId) internal {
- // TODO: Maybe force to be set on deployment?
- require(colonyBridgeAddress != address(0x0), "colony-network-foreign-bridge-not-set");
- address colonyAddress = msgSender();
- reputationUpdateCount[block.chainid][colonyAddress] += 1;
- // Build the transaction we're going to send to the bridge
- bytes memory payload = abi.encodeWithSignature(
- "addReputationUpdateLogFromBridge(address,address,int256,uint256,uint256)",
- colonyAddress,
- _user,
- _amount,
- _skillId,
- reputationUpdateCount[block.chainid][colonyAddress]
- );
-
- bool success = callThroughBridgeWithGuards(payload);
-
- if (success) {
- emit ReputationUpdateSentToBridge(
- colonyAddress,
- reputationUpdateCount[block.chainid][colonyAddress]
- );
- return;
- }
-
- // Store to resend later
- PendingReputationUpdate memory pendingReputationUpdate = PendingReputationUpdate(
- _user,
- _amount,
- _skillId,
- msgSender(),
- block.timestamp
- );
- pendingReputationUpdates[block.chainid][colonyAddress][
- reputationUpdateCount[block.chainid][colonyAddress]
- ] = pendingReputationUpdate;
-
- emit ReputationUpdateStored(colonyAddress, reputationUpdateCount[block.chainid][colonyAddress]);
- }
-
- // Mining cycle decay constants
- // Note that these values and the mining window size (defined in ReputationMiningCycleCommon)
- // need to be consistent with each other, but are not checked, in order for the decay
- // rate to be as-expected.
- int256 constant DECAY_NUMERATOR = 999679150010889; // 1-hr mining cycle
- int256 constant DECAY_DENOMINATOR = 1000000000000000;
- uint256 constant DECAY_PERIOD = 1 hours;
-
- function decayReputation(
- int256 _reputation,
- uint256 _since
- ) internal view returns (int256 decayedReputation) {
- uint256 decayEpochs = (block.timestamp - _since) / DECAY_PERIOD;
- int256 adjustedNumerator = DECAY_NUMERATOR;
-
- // This algorithm successively doubles the decay factor while halving the number of epochs
- // This allows us to perform the decay in O(log(n)) time
- // For example, a decay of 50 epochs would be applied as (k**2)(k**16)(k**32)
- while (decayEpochs > 0) {
- // slither-disable-next-line weak-prng
- if (decayEpochs % 2 >= 1) {
- // slither-disable-next-line divide-before-multiply
- _reputation = (_reputation * adjustedNumerator) / DECAY_DENOMINATOR;
- }
- // slither-disable-next-line divide-before-multiply
- adjustedNumerator = (adjustedNumerator * adjustedNumerator) / DECAY_DENOMINATOR;
- decayEpochs >>= 1;
- }
- return _reputation;
- }
-
- function callThroughBridgeWithGuards(bytes memory payload) internal returns (bool) {
- bytes memory bridgePayload = abi.encodeWithSignature(
- "sendMessage(uint256,bytes)",
- getAndCacheReputationMiningChainId(),
- payload
- );
-
- (bool success, bytes memory returnData) = callWithGuards(colonyBridgeAddress, bridgePayload);
-
- // If the function call was a success, and it returned true
- if (success) {
- bool res = abi.decode(returnData, (bool));
- return res;
- }
- return false;
- }
}
diff --git a/contracts/colonyNetwork/ColonyNetworkStorage.sol b/contracts/colonyNetwork/ColonyNetworkStorage.sol
index d544997828..c8f493d25b 100644
--- a/contracts/colonyNetwork/ColonyNetworkStorage.sol
+++ b/contracts/colonyNetwork/ColonyNetworkStorage.sol
@@ -160,35 +160,22 @@ contract ColonyNetworkStorage is ColonyNetworkDataTypes, DSMath, CommonStorage,
_;
}
- modifier onlyColonyBridge() {
- require(msgSender() == colonyBridgeAddress, "colony-network-caller-must-be-colony-bridge");
- _;
- }
-
- modifier onlyMiningChain() {
- if (getMiningChainId() == block.chainid) {
- require(
- inactiveReputationMiningCycle != address(0x0),
- "colony-reputation-mining-not-initialised"
- );
- }
- require(isMiningChain(), "colony-only-valid-on-mining-chain");
+ modifier miningInitialised() {
+ require(
+ inactiveReputationMiningCycle != address(0x0),
+ "colony-reputation-mining-not-initialised"
+ );
_;
}
- modifier onlyMiningChainOrDuringSetup() {
+ modifier miningInitialisedOrDuringSetup() {
require(
- isMiningChain() || getMiningChainId() == 0,
+ inactiveReputationMiningCycle != address(0x0) || getMiningChainId() == 0,
"colony-only-valid-on-mining-chain-or-during-setup"
);
_;
}
- modifier onlyNotMiningChain() {
- require(!isMiningChain(), "colony-only-valid-not-on-mining-chain");
- _;
- }
-
// Internal functions
function toRootSkillId(uint256 _chainId) internal pure returns (uint256) {
@@ -200,21 +187,7 @@ contract ColonyNetworkStorage is ColonyNetworkDataTypes, DSMath, CommonStorage,
return _skillId >> 128;
}
- function isMiningChain() internal view returns (bool) {
- return block.chainid == getMiningChainId();
- }
-
function getMiningChainId() public view returns (uint256) {
- if (reputationMiningChainId == 0 && isXdai()) {
- return block.chainid;
- }
- return reputationMiningChainId;
- }
-
- function getAndCacheReputationMiningChainId() internal returns (uint256) {
- if (reputationMiningChainId == 0 && isXdai()) {
- reputationMiningChainId = block.chainid;
- }
return reputationMiningChainId;
}
}
diff --git a/contracts/colonyNetwork/IColonyNetwork.sol b/contracts/colonyNetwork/IColonyNetwork.sol
index 850840598e..9636c57e6b 100644
--- a/contracts/colonyNetwork/IColonyNetwork.sol
+++ b/contracts/colonyNetwork/IColonyNetwork.sol
@@ -529,97 +529,23 @@ interface IColonyNetwork is ColonyNetworkDataTypes, IRecovery, IBasicMetaTransac
/// @return bridge The address of the bridge to the mining chain, if set
function getColonyBridgeAddress() external view returns (address bridge);
- /// @notice Update the reputation on a foreign chain from the mining chain
- /// @dev Should error if called by anyone other than the known bridge from the mining chain
- /// @param newHash The new root hash
- /// @param newNLeaves The new nLeaves in the root hash
- /// @param nonce The nonce to ensure these txs can't be replayed
- function setReputationRootHashFromBridge(
- bytes32 newHash,
- uint256 newNLeaves,
- uint256 nonce
- ) external;
-
- /// @notice Initiate a cross-chain update of the current reputation state
- /// @param chainId The chainid we want to bridge to
- function bridgeCurrentRootHash(uint256 chainId) external;
-
- /// @notice Called to re-send the bridging transaction for a skill to the
- /// @param skillId The skillId we're bridging the creation of
- function bridgeSkillIfNotMiningChain(uint256 skillId) external;
-
- /// @notice Function called by bridge transactions to add a new skill
- /// @param _parentSkillId The parent id of the new skill
- /// @param _skillCount The number of the new skill being created
- function addSkillFromBridge(uint256 _parentSkillId, uint256 _skillCount) external;
-
- /// @notice Called to add a bridged skill that wasn't next when it was bridged,
- /// but now is
- /// @param _skillId The skillId of the skill being bridged
- function addPendingSkill(uint256 _skillId) external;
-
- /// @notice Called to get the information about a skill that has been bridged out of order
- /// @param _chainId The chainId we're bridging from
- /// @param _skillCount The skill count
- /// @return parentId The parent id of the skill being added
- function getPendingSkillAddition(
- uint256 _chainId,
- uint256 _skillCount
- ) external view returns (uint256 parentId);
-
- /// @notice Get the (currently bridged) skill count of another chain
- /// @param _chainId The chainid of foreign chain
- /// @return skillCount The skillCount of the corresponding chain
- function getBridgedSkillCounts(uint256 _chainId) external view returns (uint256 skillCount);
-
- /// @notice Adds a reputation update entry to log.
- /// @dev Errors if it is called by anyone but a known bridge
- /// @param _colony The colony the reputation is being awarded in
- /// @param _user The address of the user for the reputation update
- /// @param _amount The amount of reputation change for the update, this can be a negative as well as a positive value
- /// @param _skillId The skill for the reputation update
- /// @param _updateNumber The counter used for ordering bridged updates
- function addReputationUpdateLogFromBridge(
- address _colony,
- address _user,
- int _amount,
- uint _skillId,
- uint256 _updateNumber
- ) external;
-
- /// @notice Get the (currently bridged) reputation update count of a chain
- /// @param _chainId The chainid of the chain
- /// @param _colony The colony being queried
- /// @return bridgedReputationCount The bridge reputation count of the corresponding chain
- /// @dev On the non-mining chain, this tracks the number of reputation updates that have either been bridged, or attempted to
- /// be bridged (and failed, and are now pending bridging). On the mining chain, it tracks how many have been successfully bridged
- /// and added to the log.
- function getBridgedReputationUpdateCount(
- uint256 _chainId,
- address _colony
- ) external view returns (uint256 bridgedReputationCount);
-
- /// @notice Try to bridge a reputation update that (previously) failed
- /// @param _colony The colony being queried
- /// @param _updateNumber the emission index to bridge
- function bridgePendingReputationUpdate(address _colony, uint256 _updateNumber) external;
-
- /// @notice Get the details of a reputation update that was bridged but was not added to the log because it was
- /// bridged out of order
- /// @param _chainId The chainId the update was bridged from
- /// @param _colony The colony being queried
- /// @param _updateNumber the updatenumber being queries
- /// @return update The update stored for that chain/colony/updateNumber
- function getPendingReputationUpdate(
- uint256 _chainId,
- address _colony,
- uint256 _updateNumber
- ) external view returns (PendingReputationUpdate memory update);
-
- /// @notice Try to emit the next reputation update that was bridged but previously failed, if any
- /// @param _chainId The chainId the update was bridged from
- /// @param _colony The colony being queried
- function addPendingReputationUpdate(uint256 _chainId, address _colony) external;
+ /// @notice Bridge a message to another chain
+ /// @param _chainId The chainId of the chain to bridge to
+ /// @param _payload The message to bridge
+ /// @dev This will bridge the message to the same address that requested the bridge on the other chain
+ function bridgeMessage(uint256 _chainId, bytes memory _payload) external;
+
+ /// @notice Bridge a message to the ProxyNetwork on another chain
+ /// @param _chainId The chainId of the chain to bridge to
+ /// @param _payload The message to bridge
+ /// @dev This should only be able to be called by the metacolony
+ function bridgeMessageToNetwork(uint256 _chainId, bytes memory _payload) external;
+
+ /// @notice Handles calls to create a new colony on another chain
+ /// @dev Should only be called by a colony, if you're trying to call this directly you're doing something wrong
+ /// @param _destinationChainId The chainId of the chain to create the colony on
+ /// @param _salt The salt to use for the colony creation
+ function createProxyColony(uint256 _destinationChainId, bytes32 _salt) external;
/// @notice Function called by a colony to ensure that a DomainTokenReceiver has been deployed and set up correctly
/// for a particular domain.
diff --git a/contracts/colonyNetwork/badcommit.txt b/contracts/colonyNetwork/badcommit.txt
new file mode 100644
index 0000000000..4f333ad188
--- /dev/null
+++ b/contracts/colonyNetwork/badcommit.txt
@@ -0,0 +1 @@
+e85aa86b446ac7df65ad8bdf7d146868c677255e
\ No newline at end of file
diff --git a/contracts/common/CommonDataTypes.sol b/contracts/common/CommonDataTypes.sol
new file mode 100644
index 0000000000..5422338e63
--- /dev/null
+++ b/contracts/common/CommonDataTypes.sol
@@ -0,0 +1,37 @@
+// SPDX-License-Identifier: GPL-3.0-or-later
+/*
+ This file is part of The Colony Network.
+
+ The Colony Network is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ The Colony Network is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with The Colony Network. If not, see .
+*/
+
+pragma solidity 0.8.28;
+
+// prettier-ignore
+interface CommonDataTypes {
+ struct Skill {
+ // total number of parent skills
+ uint128 nParents;
+ // total number of child skills
+ uint128 nChildren;
+ // array of `skill_id`s of parent skills starting from the 1st to `n`th, where `n` is an integer power of two larger than or equal to 1
+ uint256[] parents;
+ // array of `skill_id`s of all child skills
+ uint256[] children;
+ // `true` for a global skill reused across colonies or `false` for a skill mapped to a single colony's domain
+ bool DEPRECATED_globalSkill;
+ // `true` for a skill that is deprecated NB: deprecation is now stored locally on colonies
+ bool DEPRECATED_deprecated;
+ }
+}
diff --git a/contracts/common/DomainReceiverManagement.sol b/contracts/common/DomainReceiverManagement.sol
new file mode 100644
index 0000000000..a42d8ac974
--- /dev/null
+++ b/contracts/common/DomainReceiverManagement.sol
@@ -0,0 +1,122 @@
+// SPDX-License-Identifier: GPL-3.0-or-later
+/*
+ This file is part of The Colony Network.
+
+ The Colony Network is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ The Colony Network is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with The Colony Network. If not, see .
+*/
+
+pragma solidity 0.8.28;
+pragma experimental "ABIEncoderV2";
+
+import { MetaTransactionMsgSender } from "./MetaTransactionMsgSender.sol";
+import { DomainTokenReceiver } from "./DomainTokenReceiver.sol";
+import { ICreateX } from "./../../lib/createx/src/ICreateX.sol";
+import { EtherRouterCreate3 } from "./EtherRouterCreate3.sol";
+import { EtherRouter } from "./EtherRouter.sol";
+import { Resolver } from "./Resolver.sol";
+import { IsContract } from "./mixins/IsContract.sol";
+
+abstract contract DomainReceiverManagement is MetaTransactionMsgSender, IsContract {
+ address constant CREATEX_ADDRESS = 0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed;
+
+ function getDomainTokenReceiverResolver() public view virtual returns (address);
+ function msgSenderIsColony() internal view virtual returns (bool);
+ function isStopped() internal view virtual returns (bool);
+
+ function idempotentDeployDomainTokenReceiver(
+ uint256 _domainId
+ ) public returns (address domainTokenReceiverAddress) {
+ require(!isStopped(), "colony-domain-receiver-management-stopped");
+ require(msgSenderIsColony(), "colony-domain-receiver-management-not-colony");
+
+ address domainReceiverResolverAddress = getDomainTokenReceiverResolver();
+
+ // Calculate the address the domain should be receiving funds at
+ domainTokenReceiverAddress = getDomainTokenReceiverAddress(msgSender(), _domainId);
+
+ if (!isContract(domainTokenReceiverAddress)) {
+ // Then deploy the contract
+ bytes32 salt = getDomainTokenReceiverDeploySalt(msgSender(), _domainId);
+ address deployedAddress = deployEtherRouterViaCreateX(salt);
+ require(
+ deployedAddress == domainTokenReceiverAddress,
+ "colony-network-domain-receiver-deploy-wrong-address"
+ );
+
+ // Set up the deployed contract
+ EtherRouter(payable(domainTokenReceiverAddress)).setResolver(domainReceiverResolverAddress);
+ DomainTokenReceiver(domainTokenReceiverAddress).setColony(msgSender());
+ } else {
+ // Contract is deployed, check it's got the right resolver
+ try EtherRouter(payable(domainTokenReceiverAddress)).resolver() returns (Resolver resolver) {
+ if (address(resolver) != domainReceiverResolverAddress) {
+ EtherRouter(payable(domainTokenReceiverAddress)).setResolver(
+ domainReceiverResolverAddress
+ );
+ }
+ } catch {
+ revert("colony-network-domain-receiver-not-etherrouter");
+ }
+ }
+
+ return domainTokenReceiverAddress;
+ }
+
+ function getDomainTokenReceiverAddress(
+ address _colony,
+ uint256 _domainId
+ ) public view returns (address) {
+ bytes32 salt = getDomainTokenReceiverDeploySalt(_colony, _domainId);
+
+ // To get the correct address, we have to mimic the _guard functionality of CreateX
+ bytes32 guardedSalt = keccak256(abi.encode(bytes32(uint256(uint160(address(this)))), salt));
+ return ICreateX(CREATEX_ADDRESS).computeCreate3Address(guardedSalt);
+ }
+
+ function getDomainTokenReceiverDeploySalt(
+ address _colony,
+ uint256 _domainId
+ ) internal view returns (bytes32) {
+ // Calculate the address the domain should be receiving funds at
+ // We only want Colony Networks to be able to deploy to the same address,
+ // so we use the permissioned deploy protection feature of CreateX, and set
+ // the first 160 bits of the salt to the address of this contract.
+
+ bytes32 salt = bytes32(uint256(uint160(address(this)))) << 96;
+
+ bytes32 additionalSalt = keccak256(abi.encode(_colony, _domainId));
+ // We use the first 88 bits of the additional salt, which is a function of the colony and domainId,
+ // to add entropy in the last 88 bits of the salt
+ salt = salt | (additionalSalt >> 168);
+ // We have set the first 160 bits, and the last 88 bits of the salt
+ // Note that this leaves byte 21 of the salt as zero (0x00), which disables cross-chain
+ // redeployment protection in createX.
+ // This is intentional, as we want to allow the same receiver to be deployed on different chains
+ return salt;
+ }
+
+ function deployEtherRouterViaCreateX(bytes32 _salt) internal returns (address) {
+ EtherRouter etherRouter = EtherRouter(
+ payable(
+ ICreateX(CREATEX_ADDRESS).deployCreate3AndInit(
+ _salt,
+ type(EtherRouterCreate3).creationCode,
+ abi.encodeWithSignature("setOwner(address)", (address(this))),
+ ICreateX.Values(0, 0)
+ )
+ )
+ );
+ return address(etherRouter);
+ }
+}
diff --git a/contracts/common/GetActionSummary.sol b/contracts/common/GetActionSummary.sol
index 4eb970b9d3..fa42a366d2 100644
--- a/contracts/common/GetActionSummary.sol
+++ b/contracts/common/GetActionSummary.sol
@@ -16,11 +16,11 @@
*/
import { IColony } from "./../colony/IColony.sol";
-import { ExtractCallData } from "./ExtractCallData.sol";
+import { ExtractCallData } from "./mixins/ExtractCallData.sol";
import { GetActionDomainSkillId } from "./GetActionDomainSkillId.sol";
import { ColonyDataTypes } from "./../colony/ColonyDataTypes.sol";
import { ColonyRoles } from "./../colony/ColonyRoles.sol";
-import { Bytes4Includes } from "./Bytes4Includes.sol";
+import { Bytes4Includes } from "./mixins/Bytes4Includes.sol";
pragma solidity 0.8.28;
pragma experimental ABIEncoderV2;
diff --git a/contracts/common/Bytes4Includes.sol b/contracts/common/mixins/Bytes4Includes.sol
similarity index 100%
rename from contracts/common/Bytes4Includes.sol
rename to contracts/common/mixins/Bytes4Includes.sol
diff --git a/contracts/common/CallWithGuards.sol b/contracts/common/mixins/CallWithGuards.sol
similarity index 54%
rename from contracts/common/CallWithGuards.sol
rename to contracts/common/mixins/CallWithGuards.sol
index efdf5269ff..078b15d825 100644
--- a/contracts/common/CallWithGuards.sol
+++ b/contracts/common/mixins/CallWithGuards.sol
@@ -1,14 +1,25 @@
pragma solidity 0.8.28;
+// SPDX-License-Identifier: GPL-3.0-or-later
+/*
+ This file is part of The Colony Network.
-contract CallWithGuards {
- function isContract(address addr) internal view returns (bool) {
- uint256 size;
- assembly {
- size := extcodesize(addr)
- }
- return size > 0;
- }
+ The Colony Network is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ The Colony Network is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with The Colony Network. If not, see .
+*/
+
+import { IsContract } from "./IsContract.sol";
+contract CallWithGuards is IsContract {
function callWithGuards(
address _target,
bytes memory _payload
diff --git a/contracts/common/ExtractCallData.sol b/contracts/common/mixins/ExtractCallData.sol
similarity index 100%
rename from contracts/common/ExtractCallData.sol
rename to contracts/common/mixins/ExtractCallData.sol
diff --git a/contracts/common/mixins/IsContract.sol b/contracts/common/mixins/IsContract.sol
new file mode 100644
index 0000000000..b4c216f03c
--- /dev/null
+++ b/contracts/common/mixins/IsContract.sol
@@ -0,0 +1,28 @@
+// SPDX-License-Identifier: GPL-3.0-or-later
+/*
+ This file is part of The Colony Network.
+
+ The Colony Network is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ The Colony Network is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with The Colony Network. If not, see .
+*/
+pragma solidity 0.8.28;
+
+contract IsContract {
+ function isContract(address addr) internal view returns (bool) {
+ uint256 size;
+ assembly {
+ size := extcodesize(addr)
+ }
+ return size > 0;
+ }
+}
diff --git a/contracts/extensions/CoinMachine.sol b/contracts/extensions/CoinMachine.sol
index 20087c933e..da56ed0f9b 100644
--- a/contracts/extensions/CoinMachine.sol
+++ b/contracts/extensions/CoinMachine.sol
@@ -102,7 +102,7 @@ contract CoinMachine is ColonyExtension, BasicMetaTransaction {
/// @notice Returns the version of the extension
/// @return _version The extension's version number
function version() public pure override returns (uint256 _version) {
- return 12;
+ return 13;
}
/// @notice Called when upgrading the extension
diff --git a/contracts/extensions/EvaluatedExpenditure.sol b/contracts/extensions/EvaluatedExpenditure.sol
index 9ae94470a7..ec69f21e83 100644
--- a/contracts/extensions/EvaluatedExpenditure.sol
+++ b/contracts/extensions/EvaluatedExpenditure.sol
@@ -42,7 +42,7 @@ contract EvaluatedExpenditure is ColonyExtension, BasicMetaTransaction {
/// @notice Returns the version of the extension
/// @return _version The extension's version number
function version() public pure override returns (uint256 _version) {
- return 8;
+ return 9;
}
/// @notice Gets the next nonce for a meta-transaction
diff --git a/contracts/extensions/FundingQueue.sol b/contracts/extensions/FundingQueue.sol
index 821a7a08d8..81e9219a7f 100644
--- a/contracts/extensions/FundingQueue.sol
+++ b/contracts/extensions/FundingQueue.sol
@@ -113,7 +113,7 @@ contract FundingQueue is ColonyExtension, BasicMetaTransaction {
/// @notice Returns the version of the extension
/// @return _version The extension's version number
function version() public pure override returns (uint256 _version) {
- return 9;
+ return 10;
}
/// @notice Configures the extension
diff --git a/contracts/extensions/MultisigPermissions.sol b/contracts/extensions/MultisigPermissions.sol
index 3053f10ef6..947fc2a70e 100644
--- a/contracts/extensions/MultisigPermissions.sol
+++ b/contracts/extensions/MultisigPermissions.sol
@@ -24,7 +24,7 @@ import { IColonyNetwork } from "./../colonyNetwork/IColonyNetwork.sol";
import { ColonyNetworkDataTypes } from "./../colonyNetwork/ColonyNetworkDataTypes.sol";
import { ColonyExtensionMeta } from "./ColonyExtensionMeta.sol";
import { GetActionSummary, ActionSummary } from "./../common/GetActionSummary.sol";
-import { Bytes4Includes } from "./../common/Bytes4Includes.sol";
+import { Bytes4Includes } from "./../common/mixins/Bytes4Includes.sol";
// ignore-file-swc-108
@@ -103,7 +103,7 @@ contract MultisigPermissions is ColonyExtensionMeta, ColonyDataTypes, GetActionS
/// @notice Returns the version of the extension
/// @return _version The extension's version number
function version() public pure override returns (uint256 _version) {
- return 2;
+ return 3;
}
/// @notice Configures the extension
diff --git a/contracts/extensions/OneTxPayment.sol b/contracts/extensions/OneTxPayment.sol
index 7f6fa73384..3356f73eeb 100644
--- a/contracts/extensions/OneTxPayment.sol
+++ b/contracts/extensions/OneTxPayment.sol
@@ -58,7 +58,7 @@ contract OneTxPayment is ColonyExtension, BasicMetaTransaction {
/// @notice Returns the version of the extension
/// @return _version The extension's version number
function version() public pure override returns (uint256 _version) {
- return 9;
+ return 10;
}
/// @notice Called when upgrading the extension
@@ -108,6 +108,7 @@ contract OneTxPayment is ColonyExtension, BasicMetaTransaction {
/// @param _callerPermissionDomainId The domainId in which the _caller_ has the administration permission (must have funding in root)
/// @param _callerChildSkillIndex Index of the _callerPermissionDomainId skill.children array to get
/// @param _workers The addresses of the recipients of the payment
+ /// @param _chainIds The chainIds of the tokens being paid out
/// @param _tokens Addresses of the tokens the payments are being made in. 0x00 for Ether.
/// @param _amounts amounts of the tokens being paid out
/// @param _domainId The domainId the payment should be coming from
@@ -118,6 +119,7 @@ contract OneTxPayment is ColonyExtension, BasicMetaTransaction {
uint256 _callerPermissionDomainId,
uint256 _callerChildSkillIndex,
address payable[] memory _workers,
+ uint256[] memory _chainIds,
address[] memory _tokens,
uint256[] memory _amounts,
uint256 _domainId,
@@ -139,7 +141,7 @@ contract OneTxPayment is ColonyExtension, BasicMetaTransaction {
uint256 expenditureId = colony.makeExpenditure(1, _childSkillIndex, _domainId);
uint256 fundingPotId = colony.getExpenditure(expenditureId).fundingPotId;
- prepareFunding(_childSkillIndex, fundingPotId, _tokens, _amounts);
+ prepareFunding(_childSkillIndex, fundingPotId, _chainIds, _tokens, _amounts);
uint256 slot;
@@ -158,14 +160,60 @@ contract OneTxPayment is ColonyExtension, BasicMetaTransaction {
require(_tokens[idx] > _tokens[idx - 1], "one-tx-payment-bad-token-order");
}
- colony.setExpenditurePayout(expenditureId, slot, _tokens[idx], _amounts[idx]);
+ colony.setExpenditurePayout(expenditureId, slot, _chainIds[idx], _tokens[idx], _amounts[idx]);
}
- finalizeAndClaim(_permissionDomainId, _childSkillIndex, expenditureId, _workers, _tokens);
+ finalizeAndClaim(
+ _permissionDomainId,
+ _childSkillIndex,
+ expenditureId,
+ _workers,
+ _chainIds,
+ _tokens
+ );
emit OneTxPaymentMade(msgSender(), expenditureId, _workers.length);
}
+ /// @notice deprecated makePayment without explicit chainId paramters for multichain
+ /// @param _permissionDomainId The domainId in which the _contract_ has permissions to add a payment and fund it
+ /// @param _childSkillIndex Index of the _permissionDomainId skill.children array to get
+ /// @param _callerPermissionDomainId The domainId in which the _caller_ has permissions to add a payment and fund it
+ /// @param _callerChildSkillIndex Index of the _callerPermissionDomainId skill.children array to get
+ /// @param _workers The addresses of the recipients of the payment
+ /// @param _tokens The addresses of the token the payments are being made in. 0x00 for Ether.
+ /// @param _amounts The amounts of the tokens being paid out
+ /// @param _domainId The domainId the payment should be coming from
+ /// @param _skillId The skillId that the payment should be marked with, possibly awarding reputation in this skill.
+ function makePayment(
+ uint256 _permissionDomainId, // Unused
+ uint256 _childSkillIndex,
+ uint256 _callerPermissionDomainId,
+ uint256 _callerChildSkillIndex,
+ address payable[] memory _workers,
+ address[] memory _tokens,
+ uint256[] memory _amounts,
+ uint256 _domainId,
+ uint256 _skillId
+ ) public {
+ uint256[] memory chainIds = new uint256[](_tokens.length);
+ for (uint256 i; i < _tokens.length; i++) {
+ chainIds[i] = block.chainid;
+ }
+ makePayment(
+ _permissionDomainId,
+ _childSkillIndex,
+ _callerPermissionDomainId,
+ _callerChildSkillIndex,
+ _workers,
+ chainIds,
+ _tokens,
+ _amounts,
+ _domainId,
+ _skillId
+ );
+ }
+
/// @notice Completes a colony payment in a single transaction
/// @dev Assumes that each entity holds administration and funding roles in the same domain,
/// although contract and caller can have the permissions in different domains.
@@ -175,6 +223,7 @@ contract OneTxPayment is ColonyExtension, BasicMetaTransaction {
/// @param _callerPermissionDomainId The domainId in which the _caller_ has permissions to add a payment and fund it
/// @param _callerChildSkillIndex Index of the _callerPermissionDomainId skill.children array to get
/// @param _workers The addresses of the recipients of the payment
+ /// @param _chainIds The chainIds of the tokens being paid out
/// @param _tokens The addresses of the token the payments are being made in. 0x00 for Ether.
/// @param _amounts The amounts of the tokens being paid out
/// @param _domainId The domainId the payment should be coming from
@@ -185,6 +234,7 @@ contract OneTxPayment is ColonyExtension, BasicMetaTransaction {
uint256 _callerPermissionDomainId,
uint256 _callerChildSkillIndex,
address payable[] memory _workers,
+ uint256[] memory _chainIds,
address[] memory _tokens,
uint256[] memory _amounts,
uint256 _domainId,
@@ -214,8 +264,10 @@ contract OneTxPayment is ColonyExtension, BasicMetaTransaction {
prepareFundingWithinDomain(
_permissionDomainId,
_childSkillIndex,
+ _domainId,
domainPotId,
fundingPotId,
+ _chainIds,
_tokens,
_amounts
);
@@ -237,19 +289,68 @@ contract OneTxPayment is ColonyExtension, BasicMetaTransaction {
require(_tokens[idx] > _tokens[idx - 1], "one-tx-payment-bad-token-order");
}
- colony.setExpenditurePayout(expenditureId, slot, _tokens[idx], _amounts[idx]);
+ colony.setExpenditurePayout(expenditureId, slot, _chainIds[idx], _tokens[idx], _amounts[idx]);
}
- finalizeAndClaim(_permissionDomainId, _childSkillIndex, expenditureId, _workers, _tokens);
+ finalizeAndClaim(
+ _permissionDomainId,
+ _childSkillIndex,
+ expenditureId,
+ _workers,
+ _chainIds,
+ _tokens
+ );
emit OneTxPaymentMade(msgSender(), expenditureId, _workers.length);
}
+ /// @notice Deprecated makePaymentFundedFromDomain without explicit chainId paramters for multichain
+ /// @param _permissionDomainId The domainId in which the _contract_ has permissions to add a payment and fund it
+ /// @param _childSkillIndex Index of the _permissionDomainId skill.children array to get
+ /// @param _callerPermissionDomainId The domainId in which the _caller_ has permissions to add a payment and fund it
+ /// @param _callerChildSkillIndex Index of the _callerPermissionDomainId skill.children array to get
+ /// @param _workers The addresses of the recipients of the payment
+ /// @param _tokens The addresses of the token the payments are being made in. 0x00 for Ether.
+ /// @param _amounts The amounts of the tokens being paid out
+ /// @param _domainId The domainId the payment should be coming from
+ /// @param _skillId The skillId that the payment should be marked with, possibly awarding reputation in this skill.
+ function makePaymentFundedFromDomain(
+ uint256 _permissionDomainId,
+ uint256 _childSkillIndex,
+ uint256 _callerPermissionDomainId,
+ uint256 _callerChildSkillIndex,
+ address payable[] memory _workers,
+ address[] memory _tokens,
+ uint256[] memory _amounts,
+ uint256 _domainId,
+ uint256 _skillId
+ ) public {
+ uint256[] memory chainIds = new uint256[](_tokens.length);
+ for (uint256 i; i < _tokens.length; i++) {
+ chainIds[i] = block.chainid;
+ }
+
+ makePaymentFundedFromDomain(
+ _permissionDomainId,
+ _childSkillIndex,
+ _callerPermissionDomainId,
+ _callerChildSkillIndex,
+ _workers,
+ chainIds,
+ _tokens,
+ _amounts,
+ _domainId,
+ _skillId
+ );
+ }
+
function calculateUniqueAmounts(
+ uint256[] memory _chainIds,
address[] memory _tokens,
uint256[] memory _amounts
- ) internal pure returns (uint256, address[] memory, uint256[] memory) {
+ ) internal pure returns (uint256, uint256[] memory, address[] memory, uint256[] memory) {
uint256 uniqueTokensIdx;
+ uint256[] memory uniqueChainIds = new uint256[](_tokens.length);
address[] memory uniqueTokens = new address[](_tokens.length);
uint256[] memory uniqueAmounts = new uint256[](_tokens.length);
@@ -266,35 +367,41 @@ contract OneTxPayment is ColonyExtension, BasicMetaTransaction {
}
if (!isMatch) {
+ uniqueChainIds[uniqueTokensIdx] = _chainIds[i];
uniqueTokens[uniqueTokensIdx] = _tokens[i];
uniqueAmounts[uniqueTokensIdx] = _amounts[i];
uniqueTokensIdx++;
}
}
- return (uniqueTokensIdx, uniqueTokens, uniqueAmounts);
+ return (uniqueTokensIdx, uniqueChainIds, uniqueTokens, uniqueAmounts);
}
function prepareFunding(
uint256 _childSkillIndex,
uint256 _fundingPotId,
+ uint256[] memory _chainIds,
address[] memory _tokens,
uint256[] memory _amounts
) internal {
(
uint256 uniqueTokensIdx,
+ uint256[] memory uniqueChainIds,
address[] memory uniqueTokens,
uint256[] memory uniqueAmounts
- ) = calculateUniqueAmounts(_tokens, _amounts);
+ ) = calculateUniqueAmounts(_chainIds, _tokens, _amounts);
for (uint256 i; i < uniqueTokensIdx; i++) {
colony.moveFundsBetweenPots(
+ 1,
+ UINT256_MAX,
1,
UINT256_MAX,
_childSkillIndex,
1,
_fundingPotId,
uniqueAmounts[i],
+ uniqueChainIds[i],
uniqueTokens[i]
);
}
@@ -303,25 +410,31 @@ contract OneTxPayment is ColonyExtension, BasicMetaTransaction {
function prepareFundingWithinDomain(
uint256 _permissionDomainId,
uint256 _childSkillIndex,
+ uint256 _domainId,
uint256 _domainPotId,
uint256 _fundingPotId,
+ uint256[] memory _chainIds,
address[] memory _tokens,
uint256[] memory _amounts
) internal {
(
uint256 uniqueTokensIdx,
+ uint256[] memory uinqueChainIds,
address[] memory uniqueTokens,
uint256[] memory uniqueAmounts
- ) = calculateUniqueAmounts(_tokens, _amounts);
+ ) = calculateUniqueAmounts(_chainIds, _tokens, _amounts);
for (uint256 i; i < uniqueTokensIdx; i++) {
colony.moveFundsBetweenPots(
_permissionDomainId,
_childSkillIndex,
- _childSkillIndex,
+ _domainId,
+ UINT256_MAX,
+ UINT256_MAX,
_domainPotId,
_fundingPotId,
uniqueAmounts[i],
+ uinqueChainIds[i],
uniqueTokens[i]
);
}
@@ -336,6 +449,7 @@ contract OneTxPayment is ColonyExtension, BasicMetaTransaction {
uint256 _childSkillIndex,
uint256 _expenditureId,
address payable[] memory _workers,
+ uint256[] memory _chainIds,
address[] memory _tokens
) internal {
colony.finalizeExpenditure(_expenditureId);
@@ -361,7 +475,7 @@ contract OneTxPayment is ColonyExtension, BasicMetaTransaction {
if (idx == 0 || _workers[idx] != _workers[idx - 1]) {
slot++;
}
- colony.claimExpenditurePayout(_expenditureId, slot, _tokens[idx]);
+ colony.claimExpenditurePayout(_expenditureId, slot, _chainIds[idx], _tokens[idx]);
}
}
}
diff --git a/contracts/extensions/ReputationBootstrapper.sol b/contracts/extensions/ReputationBootstrapper.sol
index bfb266ef95..81d640971c 100644
--- a/contracts/extensions/ReputationBootstrapper.sol
+++ b/contracts/extensions/ReputationBootstrapper.sol
@@ -77,7 +77,7 @@ contract ReputationBootstrapper is ColonyExtensionMeta {
/// @notice Returns the version of the extension
/// @return _version The extension's version number
function version() public pure override returns (uint256) {
- return 6;
+ return 7;
}
/// @notice Configures the extension
diff --git a/contracts/extensions/StagedExpenditure.sol b/contracts/extensions/StagedExpenditure.sol
index 8aa8aa4965..6ab2d1adab 100644
--- a/contracts/extensions/StagedExpenditure.sol
+++ b/contracts/extensions/StagedExpenditure.sol
@@ -45,7 +45,7 @@ contract StagedExpenditure is ColonyExtensionMeta, ColonyDataTypes {
/// @notice Returns the version of the extension
/// @return _version The extension's version number
function version() public pure override returns (uint256 _version) {
- return 4;
+ return 5;
}
// Public
diff --git a/contracts/extensions/StakedExpenditure.sol b/contracts/extensions/StakedExpenditure.sol
index 8b5a29ba8c..1b482cd4fc 100644
--- a/contracts/extensions/StakedExpenditure.sol
+++ b/contracts/extensions/StakedExpenditure.sol
@@ -68,7 +68,7 @@ contract StakedExpenditure is ColonyExtensionMeta {
/// @notice Returns the version of the extension
/// @return _version The extension's version number
function version() public pure override returns (uint256 _version) {
- return 7;
+ return 8;
}
// Public
diff --git a/contracts/extensions/StreamingPayments.sol b/contracts/extensions/StreamingPayments.sol
index a42e9f88b2..012f7bf90a 100644
--- a/contracts/extensions/StreamingPayments.sol
+++ b/contracts/extensions/StreamingPayments.sol
@@ -116,7 +116,7 @@ contract StreamingPayments is ColonyExtensionMeta {
/// @notice Returns the version of the extension
/// @return _version The extension's version number
function version() public pure override returns (uint256 _version) {
- return 6;
+ return 7;
}
/// @notice Called when upgrading the extension
diff --git a/contracts/extensions/TokenSupplier.sol b/contracts/extensions/TokenSupplier.sol
index b9d4b46223..76887df174 100644
--- a/contracts/extensions/TokenSupplier.sol
+++ b/contracts/extensions/TokenSupplier.sol
@@ -74,7 +74,7 @@ contract TokenSupplier is ColonyExtension, BasicMetaTransaction {
/// @notice Returns the version of the extension
/// @return _version The extension's version number
function version() public pure override returns (uint256 _version) {
- return 9;
+ return 10;
}
/// @notice Configures the extension
diff --git a/contracts/extensions/Whitelist.sol b/contracts/extensions/Whitelist.sol
index 5a7bc4fb95..c628bad5d3 100644
--- a/contracts/extensions/Whitelist.sol
+++ b/contracts/extensions/Whitelist.sol
@@ -72,7 +72,7 @@ contract Whitelist is ColonyExtension, BasicMetaTransaction {
/// @notice Returns the version of the extension
/// @return _version The extension's version number
function version() public pure override returns (uint256 _version) {
- return 8;
+ return 9;
}
// Public
diff --git a/contracts/extensions/votingReputation/VotingReputationStorage.sol b/contracts/extensions/votingReputation/VotingReputationStorage.sol
index d4d731974d..cb01d57508 100644
--- a/contracts/extensions/votingReputation/VotingReputationStorage.sol
+++ b/contracts/extensions/votingReputation/VotingReputationStorage.sol
@@ -128,7 +128,7 @@ contract VotingReputationStorage is
/// @notice Returns the version of the extension
/// @return _version The extension's version number
function version() public pure override returns (uint256 _version) {
- return 13;
+ return 14;
}
function install(address _colony) public override {
diff --git a/contracts/testHelpers/LiFiFacetProxyMock.sol b/contracts/testHelpers/LiFiFacetProxyMock.sol
new file mode 100644
index 0000000000..edbf1236ef
--- /dev/null
+++ b/contracts/testHelpers/LiFiFacetProxyMock.sol
@@ -0,0 +1,63 @@
+// SPDX-License-Identifier: GPL-3.0-or-later
+/*
+ This file is part of The Colony Network.
+
+ The Colony Network is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ The Colony Network is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with The Colony Network. If not, see .
+*/
+
+pragma solidity 0.8.28;
+
+import { ColonyExtensionMeta } from "./../extensions/ColonyExtensionMeta.sol";
+import { IColony } from "../colony/IColony.sol";
+import { ERC20Extended } from "../common/ERC20Extended.sol";
+
+contract LiFiFacetProxyMock {
+ event SwapTokens(
+ uint256 _fromChainId,
+ address _fromToken,
+ uint256 _toChainId,
+ address _toToken,
+ address _toAddress,
+ uint256 _amount
+ );
+
+ function swapTokensMock(
+ uint256 _fromChainId,
+ address _fromToken,
+ uint256 _toChainId,
+ address _toToken,
+ address _toAddress,
+ uint256 _amount
+ ) external payable {
+ if (_fromToken == address(0)) {
+ require(msg.value == _amount, "LiFiFacetProxyMock-ether-amount-mismatch");
+ } else {
+ require(
+ ERC20Extended(_fromToken).transferFrom(msg.sender, address(this), _amount),
+ "LiFiFacetProxyMock-transferFrom-failed"
+ );
+ }
+
+ // And then emit an event that... maybe some dev utility will listen for?
+ emit SwapTokens(_fromChainId, _fromToken, _toChainId, _toToken, _toAddress, _amount);
+ }
+
+ fallback() external payable {
+ revert("LiFiFacetProxyMock-unimplemented-function");
+ }
+
+ receive() external payable {
+ revert("LiFiFacetProxyMock-unimplemented-function-2");
+ }
+}
diff --git a/contracts/testHelpers/RequireExecuteCall.sol b/contracts/testHelpers/RequireExecuteCall.sol
index 9b8b3eda6d..e5a8ecfa66 100644
--- a/contracts/testHelpers/RequireExecuteCall.sol
+++ b/contracts/testHelpers/RequireExecuteCall.sol
@@ -19,7 +19,7 @@
pragma solidity 0.8.28;
pragma experimental ABIEncoderV2;
-import { CallWithGuards } from "./../common/CallWithGuards.sol";
+import { CallWithGuards } from "./../common/mixins/CallWithGuards.sol";
contract RequireExecuteCall is CallWithGuards {
function executeCall(address target, bytes memory action) public {
diff --git a/contracts/testHelpers/WormholeMock.sol b/contracts/testHelpers/WormholeMock.sol
index 3f303b2595..dc313018b2 100644
--- a/contracts/testHelpers/WormholeMock.sol
+++ b/contracts/testHelpers/WormholeMock.sol
@@ -73,7 +73,7 @@ contract WormholeMock is IWormhole {
require(bridgeEnabled, "bridge-disabled");
cumulativeSequence += 1;
- emit LogMessagePublished(msg.sender, sequence, nonce, payload, consistencyLevel);
+ emit LogMessagePublished(msg.sender, cumulativeSequence, nonce, payload, consistencyLevel);
return cumulativeSequence;
}
diff --git a/docs/interfaces/extensions/onetxpayment.md b/docs/interfaces/extensions/onetxpayment.md
index 81ed1f179c..ab86b91403 100644
--- a/docs/interfaces/extensions/onetxpayment.md
+++ b/docs/interfaces/extensions/onetxpayment.md
@@ -152,6 +152,26 @@ Configures the extension
### â–¸ `makePayment(uint256 _permissionDomainId, uint256 _childSkillIndex, uint256 _callerPermissionDomainId, uint256 _callerChildSkillIndex, address[] memory _workers, address[] memory _tokens, uint256[] memory _amounts, uint256 _domainId, uint256 _skillId)`
+deprecated makePayment without explicit chainId paramters for multichain
+
+
+**Parameters**
+
+|Name|Type|Description|
+|---|---|---|
+|_permissionDomainId|uint256|The domainId in which the _contract_ has permissions to add a payment and fund it
+|_childSkillIndex|uint256|Index of the _permissionDomainId skill.children array to get
+|_callerPermissionDomainId|uint256|The domainId in which the _caller_ has permissions to add a payment and fund it
+|_callerChildSkillIndex|uint256|Index of the _callerPermissionDomainId skill.children array to get
+|_workers|address[]|The addresses of the recipients of the payment
+|_tokens|address[]|The addresses of the token the payments are being made in. 0x00 for Ether.
+|_amounts|uint256[]|The amounts of the tokens being paid out
+|_domainId|uint256|The domainId the payment should be coming from
+|_skillId|uint256|The skillId that the payment should be marked with, possibly awarding reputation in this skill.
+
+
+### â–¸ `makePayment(uint256 _permissionDomainId, uint256 _childSkillIndex, uint256 _callerPermissionDomainId, uint256 _callerChildSkillIndex, address[] memory _workers, uint256[] memory _chainIds, address[] memory _tokens, uint256[] memory _amounts, uint256 _domainId, uint256 _skillId)`
+
Completes a colony payment in a single transaction
*Note: Assumes that each entity holds administration and funding roles in the root domain*
@@ -165,6 +185,7 @@ Completes a colony payment in a single transaction
|_callerPermissionDomainId|uint256|The domainId in which the _caller_ has the administration permission (must have funding in root)
|_callerChildSkillIndex|uint256|Index of the _callerPermissionDomainId skill.children array to get
|_workers|address[]|The addresses of the recipients of the payment
+|_chainIds|uint256[]|The chainIds of the tokens being paid out
|_tokens|address[]|Addresses of the tokens the payments are being made in. 0x00 for Ether.
|_amounts|uint256[]|amounts of the tokens being paid out
|_domainId|uint256|The domainId the payment should be coming from
@@ -173,6 +194,26 @@ Completes a colony payment in a single transaction
### â–¸ `makePaymentFundedFromDomain(uint256 _permissionDomainId, uint256 _childSkillIndex, uint256 _callerPermissionDomainId, uint256 _callerChildSkillIndex, address[] memory _workers, address[] memory _tokens, uint256[] memory _amounts, uint256 _domainId, uint256 _skillId)`
+Deprecated makePaymentFundedFromDomain without explicit chainId paramters for multichain
+
+
+**Parameters**
+
+|Name|Type|Description|
+|---|---|---|
+|_permissionDomainId|uint256|The domainId in which the _contract_ has permissions to add a payment and fund it
+|_childSkillIndex|uint256|Index of the _permissionDomainId skill.children array to get
+|_callerPermissionDomainId|uint256|The domainId in which the _caller_ has permissions to add a payment and fund it
+|_callerChildSkillIndex|uint256|Index of the _callerPermissionDomainId skill.children array to get
+|_workers|address[]|The addresses of the recipients of the payment
+|_tokens|address[]|The addresses of the token the payments are being made in. 0x00 for Ether.
+|_amounts|uint256[]|The amounts of the tokens being paid out
+|_domainId|uint256|The domainId the payment should be coming from
+|_skillId|uint256|The skillId that the payment should be marked with, possibly awarding reputation in this skill.
+
+
+### â–¸ `makePaymentFundedFromDomain(uint256 _permissionDomainId, uint256 _childSkillIndex, uint256 _callerPermissionDomainId, uint256 _callerChildSkillIndex, address[] memory _workers, uint256[] memory _chainIds, address[] memory _tokens, uint256[] memory _amounts, uint256 _domainId, uint256 _skillId)`
+
Completes a colony payment in a single transaction
*Note: Assumes that each entity holds administration and funding roles in the same domain, although contract and caller can have the permissions in different domains. Payment is taken from domain funds - if the domain does not have sufficient funds, call will fail.*
@@ -186,6 +227,7 @@ Completes a colony payment in a single transaction
|_callerPermissionDomainId|uint256|The domainId in which the _caller_ has permissions to add a payment and fund it
|_callerChildSkillIndex|uint256|Index of the _callerPermissionDomainId skill.children array to get
|_workers|address[]|The addresses of the recipients of the payment
+|_chainIds|uint256[]|The chainIds of the tokens being paid out
|_tokens|address[]|The addresses of the token the payments are being made in. 0x00 for Ether.
|_amounts|uint256[]|The amounts of the tokens being paid out
|_domainId|uint256|The domainId the payment should be coming from
diff --git a/docs/interfaces/icolony.md b/docs/interfaces/icolony.md
index 033da0286e..624aa5ae5d 100644
--- a/docs/interfaces/icolony.md
+++ b/docs/interfaces/icolony.md
@@ -174,6 +174,19 @@ Move any funds received by the colony in `_token` denomination to the top-level
|_token|address|Address of the token, `0x0` value indicates Ether
+### â–¸ `claimColonyFunds(uint256 _chainId, address _token)`
+
+Move any funds received by the colony in `_token` denomination to the top-level domain pot, siphoning off a small amount to the reward pot. If called against a colony's own token, no fee is taken.
+
+
+**Parameters**
+
+|Name|Type|Description|
+|---|---|---|
+|_chainId|uint256|Chain id of the chain where the funds need to be claimed
+|_token|address|Address of the token, `0x0` value indicates Ether
+
+
### â–¸ `claimDomainFunds(address _token, uint256 _domainId)`
Move any funds received by the colony for a specific domain to that domain's pot Currently no fees are taken
@@ -189,6 +202,20 @@ Move any funds received by the colony for a specific domain to that domain's pot
### â–¸ `claimExpenditurePayout(uint256 _id, uint256 _slot, address _token)`
+This function is deprecated and will be removed in a future version
+
+
+**Parameters**
+
+|Name|Type|Description|
+|---|---|---|
+|_id|uint256|Expenditure identifier
+|_slot|uint256|Number of the slot
+|_token|address|Address of the token, `0x0` value indicates Ether
+
+
+### â–¸ `claimExpenditurePayout(uint256 _id, uint256 _slot, uint256 _chainId, address _token)`
+
Claim the payout for an expenditure slot. Here the network receives a fee from each payout.
@@ -198,6 +225,7 @@ Claim the payout for an expenditure slot. Here the network receives a fee from e
|---|---|---|
|_id|uint256|Expenditure identifier
|_slot|uint256|Number of the slot
+|_chainId|uint256|The chainId of the token
|_token|address|Address of the token, `0x0` value indicates Ether
@@ -218,6 +246,19 @@ Claim the reward payout at `_payoutId`. User needs to provide their reputation a
|siblings|bytes32[]|The siblings of the proof
+### â–¸ `createProxyColony(uint256 _destinationChainId, bytes32 _salt)`
+
+Create a proxy colony on another chain
+
+
+**Parameters**
+
+|Name|Type|Description|
+|---|---|---|
+|_destinationChainId|uint256|Chain id of the destination chain
+|_salt|bytes32|The colony creation salt that was used on creation of the colony
+
+
### â–¸ `deobligateStake(address _user, uint256 _domainId, uint256 _amount)`
Deobligate the user some amount of tokens, releasing the stake.
@@ -391,6 +432,25 @@ Put colony network mining into recovery mode. Can only be called by user with re
+### â–¸ `exchangeTokensViaLiFi(uint256 _permissionDomainId, uint256 _childSkillIndex, uint256 _domainId, bytes memory _txdata, uint256 _value, uint256 _chainId, address _token, uint256 _amount)`
+
+Exchange funds between two tokens, potentially between chains The tokens being swapped are held by a proxy contract
+
+
+**Parameters**
+
+|Name|Type|Description|
+|---|---|---|
+|_permissionDomainId|uint256|The domainId in which I have the permission to take this action
+|_childSkillIndex|uint256|The child index in `_permissionDomainId` where we can find `_domainId`
+|_domainId|uint256|Id of the domain
+|_txdata|bytes|Transaction data for the exchange
+|_value|uint256|Value of the transaction
+|_chainId|uint256|The chainId of the token
+|_token|address|Address of the token. If the native token is being swapped, can be anything and _amount should be 0.
+|_amount|uint256|Amount of tokens to exchange
+
+
### â–¸ `executeMetaTransaction(address userAddress, bytes memory payload, bytes32 sigR, bytes32 sigS, uint8 sigV):bytes returnData`
Executes a metatransaction targeting this contract
@@ -665,6 +725,24 @@ Get the non-mapping properties of a pot by id.
### â–¸ `getFundingPotBalance(uint256 _potId, address _token):uint256 balance`
+Deprecated - use version with explicit chainId
+
+
+**Parameters**
+
+|Name|Type|Description|
+|---|---|---|
+|_potId|uint256|Id of the funding pot
+|_token|address|Address of the token, `0x0` value indicates Ether
+
+**Return Parameters**
+
+|Name|Type|Description|
+|---|---|---|
+|balance|uint256|Funding pot supply balance
+
+### â–¸ `getFundingPotBalance(uint256 _potId, uint256 _chainId, address _token):uint256 balance`
+
Get the `_token` balance of pot with id `_potId`.
@@ -673,6 +751,7 @@ Get the `_token` balance of pot with id `_potId`.
|Name|Type|Description|
|---|---|---|
|_potId|uint256|Id of the funding pot
+|_chainId|uint256|The chainId of the token
|_token|address|Address of the token, `0x0` value indicates Ether
**Return Parameters**
@@ -762,6 +841,25 @@ Get the total amount of tokens `_token` minus amount reserved to be paid to the
|---|---|---|
|amount|uint256|Total amount of tokens in funding pots other than the rewards pot (id 0)
+### â–¸ `getNonRewardPotsTotal(uint256 _chainId, address _token):uint256 amount`
+
+Get the total amount of tokens `_token` minus amount reserved to be paid to the reputation and token holders as rewards.
+
+*Note: NB This only returns totals that the colony knows about - unclaimed funds will not be included*
+
+**Parameters**
+
+|Name|Type|Description|
+|---|---|---|
+|_chainId|uint256|Chain id to query the total for
+|_token|address|Address of the token, `0x0` value indicates Ether
+
+**Return Parameters**
+
+|Name|Type|Description|
+|---|---|---|
+|amount|uint256|Total amount of tokens in funding pots other than the rewards pot (id 0)
+
### â–¸ `getObligation(address _user, address _obligator, uint256 _domainId):uint256 obligation`
View an obligation of tokens.
@@ -1149,6 +1247,21 @@ Add a new expenditure in the colony. Secured function to authorised members.
|---|---|---|
|expenditureId|uint256|Identifier of the newly created expenditure
+### â–¸ `makeProxyArbitraryTransaction(uint256 chainId, address _destination, bytes memory _action)`
+
+Execute arbitrary transactions on behalf of the Colony via a proxy colony on another chain
+
+*Note: If proxy colony not already deployed, will do nothing*
+
+**Parameters**
+
+|Name|Type|Description|
+|---|---|---|
+|chainId|uint256|The chainId of the proxy colony
+|_destination|address|Address to be targeted
+|_action|bytes|Array of Bytes arrays encoding the function call
+
+
### â–¸ `makeSingleArbitraryTransaction(address _target, bytes memory _action):bool success`
Executes a single arbitrary transaction
@@ -1213,6 +1326,27 @@ Move a given amount: `_amount` of `_token` funds from funding pot with id `_from
|_token|address|Address of the token, `0x0` value indicates Ether
+### â–¸ `moveFundsBetweenPots(uint256 _permissionDomainId, uint256 _childSkillIndex, uint256 _domainId, uint256 _fromChildSkillIndex, uint256 _toChildSkillIndex, uint256 _fromPot, uint256 _toPot, uint256 _amount, uint256 _chainId, address _token)`
+
+Move a given amount: `_amount` of `_token` funds from funding pot with id `_fromPot` to one with id `_toPot`.
+
+
+**Parameters**
+
+|Name|Type|Description|
+|---|---|---|
+|_permissionDomainId|uint256|The domainId in which I have the permission to take this action
+|_childSkillIndex|uint256|The child index in _permissionDomainId where I will be taking this action
+|_domainId|uint256|The domain where I am taking this action, pointed to by _permissionDomainId and _childSkillIndex
+|_fromChildSkillIndex|uint256|In the array of child skills for the skill associated with the domain pointed to by _permissionDomainId + _childSkillIndex, the index of the skill associated with the domain that contains _fromPot
+|_toChildSkillIndex|uint256|The same, but for the _toPot which the funds are being moved to
+|_fromPot|uint256|Funding pot id providing the funds
+|_toPot|uint256|Funding pot id receiving the funds
+|_amount|uint256|Amount of funds
+|_chainId|uint256|The chainId of the token
+|_token|address|Address of the token, `0x0` value indicates Ether
+
+
### â–¸ `moveFundsBetweenPots(uint256 _permissionDomainId, uint256 _fromChildSkillIndex, uint256 _toChildSkillIndex, uint256 _fromPot, uint256 _toPot, uint256 _amount, address _token)`
Move a given amount: `_amount` of `_token` funds from funding pot with id `_fromPot` to one with id `_toPot`.
@@ -1287,6 +1421,21 @@ Get the owner of the contract
|---|---|---|
|owner|address|The owner of the contract
+### â–¸ `recordClaimedFundsFromBridge(uint256 _chainId, address _token, uint256 _domainId, uint256 _amount)`
+
+Used by the bridge to indicate that funds have been claimed on another chain.
+
+
+**Parameters**
+
+|Name|Type|Description|
+|---|---|---|
+|_chainId|uint256|Chain id of the chain where the funds were claimed
+|_token|address|Address of the token, `0x0` value indicates Ether
+|_domainId|uint256|Id of the domain where the funds were claimed
+|_amount|uint256|Amount of funds claimed
+
+
### â–¸ `registerColonyLabel(string memory colonyName, string memory orbitdb)`
Register colony's ENS label.
@@ -1445,8 +1594,42 @@ Set the token payout on an expenditure slot. Can only be called by expenditure o
|_amount|uint256|Payout amount
+### â–¸ `setExpenditurePayout(uint256 _id, uint256 _slot, uint256 _chainId, address _token, uint256 _amount)`
+
+Set the token payout on an expenditure slot. Can only be called by expenditure owner.
+
+*Note: Can only be called while expenditure is in draft state.*
+
+**Parameters**
+
+|Name|Type|Description|
+|---|---|---|
+|_id|uint256|Id of the expenditure
+|_slot|uint256|Number of the slot
+|_chainId|uint256|The chainId of the token
+|_token|address|Address of the token, `0x0` value indicates Ether
+|_amount|uint256|Payout amount
+
+
### â–¸ `setExpenditurePayout(uint256 _permissionDomainId, uint256 _childSkillIndex, uint256 _id, uint256 _slot, address _token, uint256 _amount)`
+This function is deprecated and will be removed in a future version
+
+
+**Parameters**
+
+|Name|Type|Description|
+|---|---|---|
+|_permissionDomainId|uint256|The domainId in which I have the permission to take this action
+|_childSkillIndex|uint256|The index that the `_domainId` is relative to `_permissionDomainId`
+|_id|uint256|Id of the expenditure
+|_slot|uint256|The slot to set the payout
+|_token|address|Address of the token, `0x0` value indicates Ether
+|_amount|uint256|Payout amount
+
+
+### â–¸ `setExpenditurePayout(uint256 _permissionDomainId, uint256 _childSkillIndex, uint256 _id, uint256 _slot, uint256 _chainId, address _token, uint256 _amount)`
+
Set the token payout in a given expenditure slot. Can only be called by an Arbitration user.
@@ -1458,6 +1641,7 @@ Set the token payout in a given expenditure slot. Can only be called by an Arbit
|_childSkillIndex|uint256|The index that the `_domainId` is relative to `_permissionDomainId`
|_id|uint256|Id of the expenditure
|_slot|uint256|The slot to set the payout
+|_chainId|uint256|The chainId of the token
|_token|address|Address of the token, `0x0` value indicates Ether
|_amount|uint256|Payout amount
diff --git a/docs/interfaces/icolonynetwork.md b/docs/interfaces/icolonynetwork.md
index 18dcd8f0e8..beb49898a3 100644
--- a/docs/interfaces/icolonynetwork.md
+++ b/docs/interfaces/icolonynetwork.md
@@ -36,48 +36,6 @@ Add a new extension resolver to the Extensions repository.
|_resolver|address|The deployed resolver containing the extension contract logic
-### â–¸ `addPendingReputationUpdate(uint256 _chainId, address _colony)`
-
-Try to emit the next reputation update that was bridged but previously failed, if any
-
-
-**Parameters**
-
-|Name|Type|Description|
-|---|---|---|
-|_chainId|uint256|The chainId the update was bridged from
-|_colony|address|The colony being queried
-
-
-### â–¸ `addPendingSkill(uint256 _skillId)`
-
-Called to add a bridged skill that wasn't next when it was bridged, but now is
-
-
-**Parameters**
-
-|Name|Type|Description|
-|---|---|---|
-|_skillId|uint256|The skillId of the skill being bridged
-
-
-### â–¸ `addReputationUpdateLogFromBridge(address _colony, address _user, int _amount, uint _skillId, uint256 _updateNumber)`
-
-Adds a reputation update entry to log.
-
-*Note: Errors if it is called by anyone but a known bridge*
-
-**Parameters**
-
-|Name|Type|Description|
-|---|---|---|
-|_colony|address|The colony the reputation is being awarded in
-|_user|address|The address of the user for the reputation update
-|_amount|int|The amount of reputation change for the update, this can be a negative as well as a positive value
-|_skillId|uint|The skill for the reputation update
-|_updateNumber|uint256|The counter used for ordering bridged updates
-
-
### â–¸ `addSkill(uint256 _parentSkillId):uint256 _skillId`
Adds a new skill to the domain or local skills tree, under skill `_parentSkillId`. Any colony is allowed to add a local skill and which is associated with a new domain via `IColony.addDomain`.
@@ -96,19 +54,6 @@ Adds a new skill to the domain or local skills tree, under skill `_parentSkillId
|---|---|---|
|_skillId|uint256|Id of the added skill
-### â–¸ `addSkillFromBridge(uint256 _parentSkillId, uint256 _skillCount)`
-
-Function called by bridge transactions to add a new skill
-
-
-**Parameters**
-
-|Name|Type|Description|
-|---|---|---|
-|_parentSkillId|uint256|The parent id of the new skill
-|_skillCount|uint256|The number of the new skill being created
-
-
### â–¸ `addr(bytes32 _node):address _address`
Returns the address the supplied node resolves do, if we are the resolver.
@@ -148,41 +93,32 @@ Indicate approval to exit recovery mode. Can only be called by user with recover
-### â–¸ `bridgeCurrentRootHash(uint256 chainId)`
+### â–¸ `bridgeMessage(uint256 _chainId, bytes memory _payload)`
-Initiate a cross-chain update of the current reputation state
+Bridge a message to another chain
+*Note: This will bridge the message to the same address that requested the bridge on the other chain*
**Parameters**
|Name|Type|Description|
|---|---|---|
-|chainId|uint256|The chainid we want to bridge to
+|_chainId|uint256|The chainId of the chain to bridge to
+|_payload|bytes|The message to bridge
-### â–¸ `bridgePendingReputationUpdate(address _colony, uint256 _updateNumber)`
+### â–¸ `bridgeMessageToNetwork(uint256 _chainId, bytes memory _payload)`
-Try to bridge a reputation update that (previously) failed
+Bridge a message to the ProxyNetwork on another chain
+*Note: This should only be able to be called by the metacolony*
**Parameters**
|Name|Type|Description|
|---|---|---|
-|_colony|address|The colony being queried
-|_updateNumber|uint256|the emission index to bridge
-
-
-### â–¸ `bridgeSkillIfNotMiningChain(uint256 skillId)`
-
-Called to re-send the bridging transaction for a skill to the
-
-
-**Parameters**
-
-|Name|Type|Description|
-|---|---|---|
-|skillId|uint256|The skillId we're bridging the creation of
+|_chainId|uint256|The chainId of the chain to bridge to
+|_payload|bytes|The message to bridge
### â–¸ `burnUnneededRewards(uint256 _amount)`
@@ -360,6 +296,20 @@ Create the Meta Colony, same as a normal colony plus the root skill.
|_tokenAddress|address|Address of the CLNY token
+### â–¸ `createProxyColony(uint256 _destinationChainId, bytes32 _salt)`
+
+Handles calls to create a new colony on another chain
+
+*Note: Should only be called by a colony, if you're trying to call this directly you're doing something wrong*
+
+**Parameters**
+
+|Name|Type|Description|
+|---|---|---|
+|_destinationChainId|uint256|The chainId of the chain to create the colony on
+|_salt|bytes32|The salt to use for the colony creation
+
+
### â–¸ `deployTokenAuthority(address _token, address _colony, address[] memory _allowedToTransfer):address _tokenAuthority`
Called to deploy a token authority
@@ -467,42 +417,6 @@ Exit recovery mode, can be called by anyone if enough whitelist approvals are gi
-### â–¸ `getBridgedReputationUpdateCount(uint256 _chainId, address _colony):uint256 bridgedReputationCount`
-
-Get the (currently bridged) reputation update count of a chain
-
-*Note: On the non-mining chain, this tracks the number of reputation updates that have either been bridged, or attempted to be bridged (and failed, and are now pending bridging). On the mining chain, it tracks how many have been successfully bridged and added to the log.*
-
-**Parameters**
-
-|Name|Type|Description|
-|---|---|---|
-|_chainId|uint256|The chainid of the chain
-|_colony|address|The colony being queried
-
-**Return Parameters**
-
-|Name|Type|Description|
-|---|---|---|
-|bridgedReputationCount|uint256|The bridge reputation count of the corresponding chain
-
-### â–¸ `getBridgedSkillCounts(uint256 _chainId):uint256 skillCount`
-
-Get the (currently bridged) skill count of another chain
-
-
-**Parameters**
-
-|Name|Type|Description|
-|---|---|---|
-|_chainId|uint256|The chainid of foreign chain
-
-**Return Parameters**
-
-|Name|Type|Description|
-|---|---|---|
-|skillCount|uint256|The skillCount of the corresponding chain
-
### â–¸ `getChildSkillId(uint256 _skillId, uint256 _childSkillIndex):uint256 _childSkillId`
Get the id of the child skill at index `_childSkillIndex` for skill with Id `_skillId`.
@@ -816,43 +730,6 @@ Get a token's status in the payout whitelist
|---|---|---|
|_status|bool|Will be `true` if token is whitelisted
-### â–¸ `getPendingReputationUpdate(uint256 _chainId, address _colony, uint256 _updateNumber):PendingReputationUpdate update`
-
-Get the details of a reputation update that was bridged but was not added to the log because it was bridged out of order
-
-
-**Parameters**
-
-|Name|Type|Description|
-|---|---|---|
-|_chainId|uint256|The chainId the update was bridged from
-|_colony|address|The colony being queried
-|_updateNumber|uint256|the updatenumber being queries
-
-**Return Parameters**
-
-|Name|Type|Description|
-|---|---|---|
-|update|PendingReputationUpdate|The update stored for that chain/colony/updateNumber
-
-### â–¸ `getPendingSkillAddition(uint256 _chainId, uint256 _skillCount):uint256 parentId`
-
-Called to get the information about a skill that has been bridged out of order
-
-
-**Parameters**
-
-|Name|Type|Description|
-|---|---|---|
-|_chainId|uint256|The chainId we're bridging from
-|_skillCount|uint256|The skill count
-
-**Return Parameters**
-
-|Name|Type|Description|
-|---|---|---|
-|parentId|uint256|The parent id of the skill being added
-
### â–¸ `getProfileDBAddress(bytes32 _node):string _orbitdb`
Retrieve the orbitdb address corresponding to a registered account.
@@ -1373,21 +1250,6 @@ Set a new Reputation root hash and starts a new mining cycle. Can only be called
|_stakers|address[]|Array of users who submitted or backed the hash, being accepted here as the new reputation root hash
-### â–¸ `setReputationRootHashFromBridge(bytes32 newHash, uint256 newNLeaves, uint256 nonce)`
-
-Update the reputation on a foreign chain from the mining chain
-
-*Note: Should error if called by anyone other than the known bridge from the mining chain*
-
-**Parameters**
-
-|Name|Type|Description|
-|---|---|---|
-|newHash|bytes32|The new root hash
-|newNLeaves|uint256|The new nLeaves in the root hash
-|nonce|uint256|The nonce to ensure these txs can't be replayed
-
-
### â–¸ `setStorageSlotRecovery(uint256 _slot, bytes32 _value)`
Update value of arbitrary storage variable. Can only be called by user with recovery role.
diff --git a/docs/interfaces/imetacolony.md b/docs/interfaces/imetacolony.md
index cab1e6ea16..9e2e7ae5d1 100644
--- a/docs/interfaces/imetacolony.md
+++ b/docs/interfaces/imetacolony.md
@@ -197,6 +197,19 @@ Move any funds received by the colony in `_token` denomination to the top-level
|_token|address|Address of the token, `0x0` value indicates Ether
+### â–¸ `claimColonyFunds(uint256 _chainId, address _token)`
+
+Move any funds received by the colony in `_token` denomination to the top-level domain pot, siphoning off a small amount to the reward pot. If called against a colony's own token, no fee is taken.
+
+
+**Parameters**
+
+|Name|Type|Description|
+|---|---|---|
+|_chainId|uint256|Chain id of the chain where the funds need to be claimed
+|_token|address|Address of the token, `0x0` value indicates Ether
+
+
### â–¸ `claimDomainFunds(address _token, uint256 _domainId)`
Move any funds received by the colony for a specific domain to that domain's pot Currently no fees are taken
@@ -212,6 +225,20 @@ Move any funds received by the colony for a specific domain to that domain's pot
### â–¸ `claimExpenditurePayout(uint256 _id, uint256 _slot, address _token)`
+This function is deprecated and will be removed in a future version
+
+
+**Parameters**
+
+|Name|Type|Description|
+|---|---|---|
+|_id|uint256|Expenditure identifier
+|_slot|uint256|Number of the slot
+|_token|address|Address of the token, `0x0` value indicates Ether
+
+
+### â–¸ `claimExpenditurePayout(uint256 _id, uint256 _slot, uint256 _chainId, address _token)`
+
Claim the payout for an expenditure slot. Here the network receives a fee from each payout.
@@ -221,6 +248,7 @@ Claim the payout for an expenditure slot. Here the network receives a fee from e
|---|---|---|
|_id|uint256|Expenditure identifier
|_slot|uint256|Number of the slot
+|_chainId|uint256|The chainId of the token
|_token|address|Address of the token, `0x0` value indicates Ether
@@ -241,6 +269,19 @@ Claim the reward payout at `_payoutId`. User needs to provide their reputation a
|siblings|bytes32[]|The siblings of the proof
+### â–¸ `createProxyColony(uint256 _destinationChainId, bytes32 _salt)`
+
+Create a proxy colony on another chain
+
+
+**Parameters**
+
+|Name|Type|Description|
+|---|---|---|
+|_destinationChainId|uint256|Chain id of the destination chain
+|_salt|bytes32|The colony creation salt that was used on creation of the colony
+
+
### â–¸ `deobligateStake(address _user, uint256 _domainId, uint256 _amount)`
Deobligate the user some amount of tokens, releasing the stake.
@@ -414,6 +455,25 @@ Put colony network mining into recovery mode. Can only be called by user with re
+### â–¸ `exchangeTokensViaLiFi(uint256 _permissionDomainId, uint256 _childSkillIndex, uint256 _domainId, bytes memory _txdata, uint256 _value, uint256 _chainId, address _token, uint256 _amount)`
+
+Exchange funds between two tokens, potentially between chains The tokens being swapped are held by a proxy contract
+
+
+**Parameters**
+
+|Name|Type|Description|
+|---|---|---|
+|_permissionDomainId|uint256|The domainId in which I have the permission to take this action
+|_childSkillIndex|uint256|The child index in `_permissionDomainId` where we can find `_domainId`
+|_domainId|uint256|Id of the domain
+|_txdata|bytes|Transaction data for the exchange
+|_value|uint256|Value of the transaction
+|_chainId|uint256|The chainId of the token
+|_token|address|Address of the token. If the native token is being swapped, can be anything and _amount should be 0.
+|_amount|uint256|Amount of tokens to exchange
+
+
### â–¸ `executeMetaTransaction(address userAddress, bytes memory payload, bytes32 sigR, bytes32 sigS, uint8 sigV):bytes returnData`
Executes a metatransaction targeting this contract
@@ -688,6 +748,24 @@ Get the non-mapping properties of a pot by id.
### â–¸ `getFundingPotBalance(uint256 _potId, address _token):uint256 balance`
+Deprecated - use version with explicit chainId
+
+
+**Parameters**
+
+|Name|Type|Description|
+|---|---|---|
+|_potId|uint256|Id of the funding pot
+|_token|address|Address of the token, `0x0` value indicates Ether
+
+**Return Parameters**
+
+|Name|Type|Description|
+|---|---|---|
+|balance|uint256|Funding pot supply balance
+
+### â–¸ `getFundingPotBalance(uint256 _potId, uint256 _chainId, address _token):uint256 balance`
+
Get the `_token` balance of pot with id `_potId`.
@@ -696,6 +774,7 @@ Get the `_token` balance of pot with id `_potId`.
|Name|Type|Description|
|---|---|---|
|_potId|uint256|Id of the funding pot
+|_chainId|uint256|The chainId of the token
|_token|address|Address of the token, `0x0` value indicates Ether
**Return Parameters**
@@ -785,6 +864,25 @@ Get the total amount of tokens `_token` minus amount reserved to be paid to the
|---|---|---|
|amount|uint256|Total amount of tokens in funding pots other than the rewards pot (id 0)
+### â–¸ `getNonRewardPotsTotal(uint256 _chainId, address _token):uint256 amount`
+
+Get the total amount of tokens `_token` minus amount reserved to be paid to the reputation and token holders as rewards.
+
+*Note: NB This only returns totals that the colony knows about - unclaimed funds will not be included*
+
+**Parameters**
+
+|Name|Type|Description|
+|---|---|---|
+|_chainId|uint256|Chain id to query the total for
+|_token|address|Address of the token, `0x0` value indicates Ether
+
+**Return Parameters**
+
+|Name|Type|Description|
+|---|---|---|
+|amount|uint256|Total amount of tokens in funding pots other than the rewards pot (id 0)
+
### â–¸ `getObligation(address _user, address _obligator, uint256 _domainId):uint256 obligation`
View an obligation of tokens.
@@ -1187,6 +1285,21 @@ Add a new expenditure in the colony. Secured function to authorised members.
|---|---|---|
|expenditureId|uint256|Identifier of the newly created expenditure
+### â–¸ `makeProxyArbitraryTransaction(uint256 chainId, address _destination, bytes memory _action)`
+
+Execute arbitrary transactions on behalf of the Colony via a proxy colony on another chain
+
+*Note: If proxy colony not already deployed, will do nothing*
+
+**Parameters**
+
+|Name|Type|Description|
+|---|---|---|
+|chainId|uint256|The chainId of the proxy colony
+|_destination|address|Address to be targeted
+|_action|bytes|Array of Bytes arrays encoding the function call
+
+
### â–¸ `makeSingleArbitraryTransaction(address _target, bytes memory _action):bool success`
Executes a single arbitrary transaction
@@ -1251,6 +1364,27 @@ Move a given amount: `_amount` of `_token` funds from funding pot with id `_from
|_token|address|Address of the token, `0x0` value indicates Ether
+### â–¸ `moveFundsBetweenPots(uint256 _permissionDomainId, uint256 _childSkillIndex, uint256 _domainId, uint256 _fromChildSkillIndex, uint256 _toChildSkillIndex, uint256 _fromPot, uint256 _toPot, uint256 _amount, uint256 _chainId, address _token)`
+
+Move a given amount: `_amount` of `_token` funds from funding pot with id `_fromPot` to one with id `_toPot`.
+
+
+**Parameters**
+
+|Name|Type|Description|
+|---|---|---|
+|_permissionDomainId|uint256|The domainId in which I have the permission to take this action
+|_childSkillIndex|uint256|The child index in _permissionDomainId where I will be taking this action
+|_domainId|uint256|The domain where I am taking this action, pointed to by _permissionDomainId and _childSkillIndex
+|_fromChildSkillIndex|uint256|In the array of child skills for the skill associated with the domain pointed to by _permissionDomainId + _childSkillIndex, the index of the skill associated with the domain that contains _fromPot
+|_toChildSkillIndex|uint256|The same, but for the _toPot which the funds are being moved to
+|_fromPot|uint256|Funding pot id providing the funds
+|_toPot|uint256|Funding pot id receiving the funds
+|_amount|uint256|Amount of funds
+|_chainId|uint256|The chainId of the token
+|_token|address|Address of the token, `0x0` value indicates Ether
+
+
### â–¸ `moveFundsBetweenPots(uint256 _permissionDomainId, uint256 _fromChildSkillIndex, uint256 _toChildSkillIndex, uint256 _fromPot, uint256 _toPot, uint256 _amount, address _token)`
Move a given amount: `_amount` of `_token` funds from funding pot with id `_fromPot` to one with id `_toPot`.
@@ -1287,6 +1421,19 @@ Call multiple functions in the current contract and return the data from all of
|---|---|---|
|results|bytes[]|The results from each of the calls passed in via data
+### â–¸ `multicallProxyNetwork(uint256 _chainId, bytes[] memory _actions)`
+
+Call (a) function(s) on the proxyColonyNetwork on a different chain
+
+
+**Parameters**
+
+|Name|Type|Description|
+|---|---|---|
+|_chainId|uint256|The chainId of the chain the function is being called on
+|_actions|bytes[]|The actions to be called
+
+
### â–¸ `numRecoveryRoles():uint64 numRoles`
Return number of recovery roles.
@@ -1325,6 +1472,21 @@ Get the owner of the contract
|---|---|---|
|owner|address|The owner of the contract
+### â–¸ `recordClaimedFundsFromBridge(uint256 _chainId, address _token, uint256 _domainId, uint256 _amount)`
+
+Used by the bridge to indicate that funds have been claimed on another chain.
+
+
+**Parameters**
+
+|Name|Type|Description|
+|---|---|---|
+|_chainId|uint256|Chain id of the chain where the funds were claimed
+|_token|address|Address of the token, `0x0` value indicates Ether
+|_domainId|uint256|Id of the domain where the funds were claimed
+|_amount|uint256|Amount of funds claimed
+
+
### â–¸ `registerColonyLabel(string memory colonyName, string memory orbitdb)`
Register colony's ENS label.
@@ -1495,8 +1657,42 @@ Set the token payout on an expenditure slot. Can only be called by expenditure o
|_amount|uint256|Payout amount
+### â–¸ `setExpenditurePayout(uint256 _id, uint256 _slot, uint256 _chainId, address _token, uint256 _amount)`
+
+Set the token payout on an expenditure slot. Can only be called by expenditure owner.
+
+*Note: Can only be called while expenditure is in draft state.*
+
+**Parameters**
+
+|Name|Type|Description|
+|---|---|---|
+|_id|uint256|Id of the expenditure
+|_slot|uint256|Number of the slot
+|_chainId|uint256|The chainId of the token
+|_token|address|Address of the token, `0x0` value indicates Ether
+|_amount|uint256|Payout amount
+
+
### â–¸ `setExpenditurePayout(uint256 _permissionDomainId, uint256 _childSkillIndex, uint256 _id, uint256 _slot, address _token, uint256 _amount)`
+This function is deprecated and will be removed in a future version
+
+
+**Parameters**
+
+|Name|Type|Description|
+|---|---|---|
+|_permissionDomainId|uint256|The domainId in which I have the permission to take this action
+|_childSkillIndex|uint256|The index that the `_domainId` is relative to `_permissionDomainId`
+|_id|uint256|Id of the expenditure
+|_slot|uint256|The slot to set the payout
+|_token|address|Address of the token, `0x0` value indicates Ether
+|_amount|uint256|Payout amount
+
+
+### â–¸ `setExpenditurePayout(uint256 _permissionDomainId, uint256 _childSkillIndex, uint256 _id, uint256 _slot, uint256 _chainId, address _token, uint256 _amount)`
+
Set the token payout in a given expenditure slot. Can only be called by an Arbitration user.
@@ -1508,6 +1704,7 @@ Set the token payout in a given expenditure slot. Can only be called by an Arbit
|_childSkillIndex|uint256|The index that the `_domainId` is relative to `_permissionDomainId`
|_id|uint256|Id of the expenditure
|_slot|uint256|The slot to set the payout
+|_chainId|uint256|The chainId of the token
|_token|address|Address of the token, `0x0` value indicates Ether
|_amount|uint256|Payout amount
diff --git a/hardhat.config.js b/hardhat.config.js
index dae5f37394..b582deb7ac 100644
--- a/hardhat.config.js
+++ b/hardhat.config.js
@@ -81,6 +81,12 @@ task("test", "Run tests").setAction(async () => {
}
});
+task("ensure-createx-deployed", "Ensure CreateX is deployed").setAction(async () => {
+ const { idempotentDeployCreateX } = require("./helpers/test-helper"); // eslint-disable-line global-require
+
+ await idempotentDeployCreateX();
+});
+
task("node", "Run a node, and output ganache-accounts.json for backwards-compatability").setAction(async () => {
const ganacheAccounts = { addresses: {}, private_keys: {} };
// eslint-disable-next-line no-restricted-syntax
@@ -102,6 +108,12 @@ task("deploy", "Deploy Colony Network as per truffle-fixture.js").setAction(asyn
await deployNetwork();
});
+task("deploy-proxy-network", "Deploy Proxy Colony Network").setAction(async () => {
+ const deployProxyNetwork = require("./test/deploy-proxy-network-fixture"); // eslint-disable-line global-require
+
+ await deployProxyNetwork();
+});
+
module.exports = {
defaultNetwork: "hardhat",
solidity: {
@@ -109,6 +121,7 @@ module.exports = {
{
version: "0.8.28",
settings: {
+ viaIR: true,
optimizer: {
enabled: true,
runs: 200,
@@ -203,6 +216,11 @@ module.exports = {
cancun: 0,
},
},
+ 265669101: {
+ hardforkHistory: {
+ cancun: 0,
+ },
+ },
},
},
},
diff --git a/helpers/constants.js b/helpers/constants.js
index 47404938f8..a5b0f12647 100644
--- a/helpers/constants.js
+++ b/helpers/constants.js
@@ -82,6 +82,12 @@ const MAINNET_CHAINID = 1;
const FORKED_MAINNET_CHAINID = 2656691;
const CREATEX_ADDRESS = "0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed";
+const LIFI_ADDRESS = "0x1231DEB6f5749EF6cE6943a275A1D3E7486F4EaE";
+const NETWORK_ADDRESS = "0x777760996135F0791E2e1a74aFAa060711197777";
+
+const PANIC = {
+ ARITHMETHIC_OVERFLOW: 17,
+};
module.exports = {
UINT256_MAX,
@@ -140,4 +146,7 @@ module.exports = {
MAINNET_CHAINID,
FORKED_MAINNET_CHAINID,
CREATEX_ADDRESS,
+ NETWORK_ADDRESS,
+ LIFI_ADDRESS,
+ PANIC,
};
diff --git a/helpers/test-data-generator.js b/helpers/test-data-generator.js
index 30deb98ace..a6b810d846 100644
--- a/helpers/test-data-generator.js
+++ b/helpers/test-data-generator.js
@@ -3,7 +3,18 @@
const BN = require("bn.js");
const { signTypedData_v4: signTypedData } = require("eth-sig-util");
-const { UINT256_MAX, MANAGER_PAYOUT, EVALUATOR_PAYOUT, WORKER_PAYOUT, INITIAL_FUNDING, SLOT0, SLOT1, SLOT2, ADDRESS_ZERO } = require("./constants");
+const {
+ UINT256_MAX,
+ MANAGER_PAYOUT,
+ EVALUATOR_PAYOUT,
+ WORKER_PAYOUT,
+ INITIAL_FUNDING,
+ SLOT0,
+ SLOT1,
+ SLOT2,
+ ADDRESS_ZERO,
+ NETWORK_ADDRESS,
+} = require("./constants");
const { getTokenArgs, web3GetAccounts, getChildSkillIndex, getChainId } = require("./test-helper");
@@ -226,8 +237,7 @@ exports.unlockCLNYToken = async function unlockCLNYToken(metaColony) {
};
exports.setupColonyNetwork = async function setupColonyNetwork() {
- const cnAddress = (await EtherRouter.deployed()).address;
- const deployedColonyNetwork = await IColonyNetwork.at(cnAddress);
+ const deployedColonyNetwork = await IColonyNetwork.at(NETWORK_ADDRESS);
// Make a new ColonyNetwork
const etherRouter = await EtherRouter.new();
@@ -303,12 +313,15 @@ exports.setupColony = async function setupColony(colonyNetwork, tokenAddress, ve
return colony;
};
-exports.getMetaTransactionParameters = async function getMetaTransactionParameters(txData, userAddress, targetAddress) {
+exports.getMetaTransactionParameters = async function getMetaTransactionParameters(txData, userAddress, targetAddress, _chainId) {
const contract = await BasicMetaTransaction.at(targetAddress);
const nonce = await contract.getMetatransactionNonce(userAddress);
// We should just be able to get the chain id via a web3 call, but until ganache sort their stuff out,
// we dance around the houses.
- const chainId = await getChainId();
+ let chainId = _chainId;
+ if (!chainId) {
+ chainId = await getChainId();
+ }
// Sign data
const msg = web3.utils.soliditySha3(
diff --git a/helpers/test-helper.js b/helpers/test-helper.js
index ea1ffcb554..b4a9bcb512 100644
--- a/helpers/test-helper.js
+++ b/helpers/test-helper.js
@@ -244,6 +244,9 @@ exports.checkErrorRevertEthers = async function checkErrorRevertEthers(promise,
let receipt;
try {
receipt = await promise;
+ if (receipt.status === 0) {
+ throw receipt;
+ }
} catch (err) {
const txid = err.transactionHash;
@@ -269,7 +272,12 @@ exports.checkErrorRevertEthers = async function checkErrorRevertEthers(promise,
},
receipt.blockNumber,
);
- reason = web3.eth.abi.decodeParameter("string", callResult.slice(10));
+ console.log("callResult", callResult);
+ if (typeof errorMessage === "number") {
+ reason = parseInt(callResult.slice(10), 16);
+ } else {
+ reason = web3.eth.abi.decodeParameter("string", callResult.slice(10));
+ }
} catch (err2) {
reason = web3.eth.abi.decodeParameter("string", err2.error.error.data.slice(10));
}
diff --git a/helpers/upgradable-contracts.js b/helpers/upgradable-contracts.js
index abf1a55ba1..67bb2a53b8 100644
--- a/helpers/upgradable-contracts.js
+++ b/helpers/upgradable-contracts.js
@@ -5,6 +5,7 @@ const fs = require("fs");
function readArtifact(contractDir, contractName) {
const artifactPath = `./artifacts/contracts/${contractDir}/${contractName}.sol/${contractName}.json`;
+ console.log(artifactPath);
try {
return JSON.parse(fs.readFileSync(artifactPath, "utf8"));
} catch (err) {
@@ -85,7 +86,10 @@ exports.setupEtherRouter = async function setupEtherRouter(contractDir, interfac
const sig = `${fName}(${iAbi[i].inputs.map((parameter) => parameter.type).join(",")})`;
const address = functionsToResolve[fName].definedIn;
try {
- await resolver.register(sig, address);
+ const txOrReceipt = await resolver.register(sig, address);
+ if (txOrReceipt.wait) {
+ await txOrReceipt.wait();
+ }
} catch (err) {
console.log(err);
throw new Error(`${sig} could not be registered. Is it defined?`);
@@ -139,7 +143,6 @@ exports.setupUpgradableColonyNetwork = async function setupUpgradableColonyNetwo
deployedImplementations.ColonyNetworkMining = colonyNetworkMining.address;
deployedImplementations.ColonyNetworkAuction = colonyNetworkAuction.address;
deployedImplementations.ColonyNetworkENS = colonyNetworkENS.address;
- deployedImplementations.ColonyNetworkSkills = colonyNetworkSkills.address;
deployedImplementations.ColonyNetworkExtensions = colonyNetworkExtensions.address;
deployedImplementations.ColonyNetworkSkills = colonyNetworkSkills.address;
deployedImplementations.ContractRecovery = contractRecovery.address;
@@ -196,3 +199,14 @@ exports.setupENSRegistrar = async function setupENSRegistrar(colonyNetwork, ensR
await ensRegistry.setSubnodeOwner(rootNode, USER_HASH, colonyNetwork.address);
await ensRegistry.setSubnodeOwner(rootNode, COLONY_HASH, colonyNetwork.address);
};
+
+exports.setupProxyColonyNetwork = async function setupProxyColonyNetwork(etherRouter, proxyColonyNetworkImplementation, resolver) {
+ const deployedImplementations = {};
+ deployedImplementations.ProxyColonyNetwork = proxyColonyNetworkImplementation.address;
+
+ await exports.setupEtherRouter("bridging", "ProxyColonyNetwork", deployedImplementations, resolver);
+ const txOrReceipt = await etherRouter.setResolver(resolver.address);
+ if (txOrReceipt.wait) {
+ await txOrReceipt.wait();
+ }
+};
diff --git a/helpers/wormholescanMock/.gitignore b/helpers/wormholescanMock/.gitignore
new file mode 100644
index 0000000000..4267c370d8
--- /dev/null
+++ b/helpers/wormholescanMock/.gitignore
@@ -0,0 +1,5 @@
+wwwroot/*.js
+node_modules
+typings
+dist
+openapi-generated-types
\ No newline at end of file
diff --git a/helpers/wormholescanMock/nodemon.json b/helpers/wormholescanMock/nodemon.json
new file mode 100644
index 0000000000..783a783697
--- /dev/null
+++ b/helpers/wormholescanMock/nodemon.json
@@ -0,0 +1,5 @@
+{
+ "watch": ["src"],
+ "ext": "ts",
+ "exec": "concurrently 'npx tsc --watch' 'ts-node src/index.ts'"
+ }
\ No newline at end of file
diff --git a/helpers/wormholescanMock/openapitools.json b/helpers/wormholescanMock/openapitools.json
new file mode 100644
index 0000000000..7dd53c5b7f
--- /dev/null
+++ b/helpers/wormholescanMock/openapitools.json
@@ -0,0 +1,14 @@
+{
+ "$schema": "./node_modules/@openapitools/openapi-generator-cli/config.schema.json",
+ "spaces": 2,
+ "generator-cli": {
+ "version": "7.10.0",
+ "generators": {
+ "typescript-fetch": {
+ "generatorName": "typescript-fetch",
+ "inputSpec": "https://api.wormholescan.io/swagger.json",
+ "output": "#{cwd}/openapi-generated-types"
+ }
+ }
+ }
+}
diff --git a/helpers/wormholescanMock/package-lock.json b/helpers/wormholescanMock/package-lock.json
new file mode 100644
index 0000000000..bdbdb3dbfb
--- /dev/null
+++ b/helpers/wormholescanMock/package-lock.json
@@ -0,0 +1,1945 @@
+{
+ "name": "wormholescanmock",
+ "version": "1.0.0",
+ "lockfileVersion": 3,
+ "requires": true,
+ "packages": {
+ "": {
+ "name": "wormholescanmock",
+ "version": "1.0.0",
+ "license": "ISC",
+ "dependencies": {
+ "@apidevtools/swagger-express-middleware": "^4.0.2",
+ "@openapitools/openapi-generator-cli": "^2.15.3",
+ "@smartrecruiters/openapi-first": "^1.2.0",
+ "@types/swagger-express-middleware": "^1.0.16",
+ "express": "^4.21.1",
+ "swagger-typescript-codegen": "^3.2.4"
+ },
+ "devDependencies": {
+ "@types/express": "^5.0.0",
+ "@types/node": "^22.10.0",
+ "typescript": "^5.7.2"
+ }
+ },
+ "../../node_modules/.pnpm/@apidevtools+swagger-express-middleware@4.0.2_express@4.21.1_openapi-types@12.1.3/node_modules/@apidevtools/swagger-express-middleware": {
+ "version": "4.0.2",
+ "license": "MIT",
+ "dependencies": {
+ "@apidevtools/swagger-methods": "^3.0.2",
+ "@apidevtools/swagger-parser": "^10.0.1",
+ "@jsdevtools/ono": "^7.1.3",
+ "body-parser": "^1.19.0",
+ "cookie-parser": "^1.4.4",
+ "debug": "^4.1.1",
+ "lodash": "^4.17.19",
+ "multer": "^1.4.2",
+ "tmp": "^0.2.1",
+ "tv4": "^1.2.5",
+ "type-is": "^1.6.18"
+ },
+ "devDependencies": {
+ "@jsdevtools/eslint-config": "^1.1.0",
+ "@jsdevtools/version-bump-prompt": "^6.0.6",
+ "basic-auth": "^2.0.1",
+ "chai": "^4.2.0",
+ "chai-datetime": "^1.7.0",
+ "eslint": "^7.6.0",
+ "express": "^4.17.1",
+ "mocha": "^8.1.0",
+ "npm-check": "^5.9.0",
+ "nyc": "^15.1.0",
+ "shx": "^0.3.2",
+ "sinon": "^9.0.2",
+ "supertest": "^4.0.2"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "peerDependencies": {
+ "express": "4.x"
+ }
+ },
+ "../../node_modules/.pnpm/@smartrecruiters+openapi-first@1.2.0/node_modules/@smartrecruiters/openapi-first": {
+ "version": "1.2.0",
+ "license": "MIT",
+ "dependencies": {
+ "lodash": "4.17.21",
+ "type-is": "1.6.18"
+ },
+ "devDependencies": {
+ "@smartrecruiters/eslint-config": "5.0.2",
+ "chai": "4.3.4",
+ "eslint": "7.30.0",
+ "eslint-plugin-security": "1.4.0",
+ "express": "4.17.1",
+ "mocha": "9.0.2",
+ "nyc": "15.1.0",
+ "sinon": "11.1.1"
+ },
+ "engines": {
+ "node": ">=10.0.0"
+ }
+ },
+ "../../node_modules/.pnpm/@types+express@5.0.0/node_modules/@types/express": {
+ "version": "5.0.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/body-parser": "*",
+ "@types/express-serve-static-core": "^5.0.0",
+ "@types/qs": "*",
+ "@types/serve-static": "*"
+ }
+ },
+ "../../node_modules/.pnpm/@types+node@22.10.0/node_modules/@types/node": {
+ "version": "22.10.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "undici-types": "~6.20.0"
+ }
+ },
+ "../../node_modules/.pnpm/@types+swagger-express-middleware@1.0.16/node_modules/@types/swagger-express-middleware": {
+ "version": "1.0.16",
+ "license": "MIT",
+ "dependencies": {
+ "@types/express": "*",
+ "swagger-parser": "^7.0.1"
+ }
+ },
+ "../../node_modules/.pnpm/express@4.21.1/node_modules/express": {
+ "version": "4.21.1",
+ "license": "MIT",
+ "dependencies": {
+ "accepts": "~1.3.8",
+ "array-flatten": "1.1.1",
+ "body-parser": "1.20.3",
+ "content-disposition": "0.5.4",
+ "content-type": "~1.0.4",
+ "cookie": "0.7.1",
+ "cookie-signature": "1.0.6",
+ "debug": "2.6.9",
+ "depd": "2.0.0",
+ "encodeurl": "~2.0.0",
+ "escape-html": "~1.0.3",
+ "etag": "~1.8.1",
+ "finalhandler": "1.3.1",
+ "fresh": "0.5.2",
+ "http-errors": "2.0.0",
+ "merge-descriptors": "1.0.3",
+ "methods": "~1.1.2",
+ "on-finished": "2.4.1",
+ "parseurl": "~1.3.3",
+ "path-to-regexp": "0.1.10",
+ "proxy-addr": "~2.0.7",
+ "qs": "6.13.0",
+ "range-parser": "~1.2.1",
+ "safe-buffer": "5.2.1",
+ "send": "0.19.0",
+ "serve-static": "1.16.2",
+ "setprototypeof": "1.2.0",
+ "statuses": "2.0.1",
+ "type-is": "~1.6.18",
+ "utils-merge": "1.0.1",
+ "vary": "~1.1.2"
+ },
+ "devDependencies": {
+ "after": "0.8.2",
+ "connect-redis": "3.4.2",
+ "cookie-parser": "1.4.6",
+ "cookie-session": "2.0.0",
+ "ejs": "3.1.9",
+ "eslint": "8.47.0",
+ "express-session": "1.17.2",
+ "hbs": "4.2.0",
+ "marked": "0.7.0",
+ "method-override": "3.0.0",
+ "mocha": "10.2.0",
+ "morgan": "1.10.0",
+ "nyc": "15.1.0",
+ "pbkdf2-password": "1.2.1",
+ "supertest": "6.3.0",
+ "vhost": "~3.0.2"
+ },
+ "engines": {
+ "node": ">= 0.10.0"
+ }
+ },
+ "../../node_modules/.pnpm/swagger-typescript-codegen@3.2.4/node_modules/swagger-typescript-codegen": {
+ "version": "3.2.4",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "commander": "^2.19.0",
+ "js-beautify": "^1.8.9",
+ "jshint": "^2.9.7",
+ "lodash": "^4.17.19",
+ "mustache": "^3.0.1",
+ "update-notifier": "^4.1.0"
+ },
+ "bin": {
+ "swagger2ts": "bin/swagger2ts.js"
+ },
+ "devDependencies": {
+ "@types/commander": "^2.12.2",
+ "@types/jest": "^23.3.10",
+ "@types/js-beautify": "^1.8.0",
+ "@types/lodash": "^4.14.119",
+ "@types/mustache": "^0.8.32",
+ "@types/node": "^10.12.18",
+ "final-fs": "^1.6.0",
+ "grunt": "^1.0.3",
+ "grunt-contrib-jshint": "^2.0.0",
+ "grunt-jsonlint": "^1.0.4",
+ "grunt-vows": "^0.4.1",
+ "husky": "^1.3.1",
+ "jest": "^23.6.0",
+ "lint-staged": "^8.1.0",
+ "matchdep": "^2.0.0",
+ "prettier": "1.15.3",
+ "request": "^2.88.0",
+ "superagent": "^4.0.0",
+ "tmp": "0.0.33",
+ "typescript": "^3.2.2",
+ "vows": "^0.8.2"
+ }
+ },
+ "../../node_modules/.pnpm/typescript@5.7.2/node_modules/typescript": {
+ "version": "5.7.2",
+ "dev": true,
+ "license": "Apache-2.0",
+ "bin": {
+ "tsc": "bin/tsc",
+ "tsserver": "bin/tsserver"
+ },
+ "devDependencies": {
+ "@dprint/formatter": "^0.4.1",
+ "@dprint/typescript": "0.93.0",
+ "@esfx/canceltoken": "^1.0.0",
+ "@eslint/js": "^9.11.1",
+ "@octokit/rest": "^21.0.2",
+ "@types/chai": "^4.3.20",
+ "@types/diff": "^5.2.2",
+ "@types/minimist": "^1.2.5",
+ "@types/mocha": "^10.0.8",
+ "@types/ms": "^0.7.34",
+ "@types/node": "latest",
+ "@types/source-map-support": "^0.5.10",
+ "@types/which": "^3.0.4",
+ "@typescript-eslint/rule-tester": "^8.8.0",
+ "@typescript-eslint/type-utils": "^8.8.0",
+ "@typescript-eslint/utils": "^8.8.0",
+ "azure-devops-node-api": "^14.1.0",
+ "c8": "^10.1.2",
+ "chai": "^4.5.0",
+ "chalk": "^4.1.2",
+ "chokidar": "^3.6.0",
+ "diff": "^5.2.0",
+ "dprint": "^0.47.2",
+ "esbuild": "^0.24.0",
+ "eslint": "^9.11.1",
+ "eslint-formatter-autolinkable-stylish": "^1.4.0",
+ "eslint-plugin-regexp": "^2.6.0",
+ "fast-xml-parser": "^4.5.0",
+ "glob": "^10.4.5",
+ "globals": "^15.9.0",
+ "hereby": "^1.10.0",
+ "jsonc-parser": "^3.3.1",
+ "knip": "^5.30.6",
+ "minimist": "^1.2.8",
+ "mocha": "^10.7.3",
+ "mocha-fivemat-progress-reporter": "^0.1.0",
+ "monocart-coverage-reports": "^2.11.0",
+ "ms": "^2.1.3",
+ "playwright": "^1.47.2",
+ "source-map-support": "^0.5.21",
+ "tslib": "^2.7.0",
+ "typescript": "^5.6.2",
+ "typescript-eslint": "^8.8.0",
+ "which": "^3.0.1"
+ },
+ "engines": {
+ "node": ">=14.17"
+ }
+ },
+ "node_modules/@apidevtools/swagger-express-middleware": {
+ "resolved": "../../node_modules/.pnpm/@apidevtools+swagger-express-middleware@4.0.2_express@4.21.1_openapi-types@12.1.3/node_modules/@apidevtools/swagger-express-middleware",
+ "link": true
+ },
+ "node_modules/@babel/runtime": {
+ "version": "7.26.0",
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.26.0.tgz",
+ "integrity": "sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw==",
+ "license": "MIT",
+ "dependencies": {
+ "regenerator-runtime": "^0.14.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@lukeed/csprng": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@lukeed/csprng/-/csprng-1.1.0.tgz",
+ "integrity": "sha512-Z7C/xXCiGWsg0KuKsHTKJxbWhpI3Vs5GwLfOean7MGyVFGqdRgBbAjOCh6u4bbjPc/8MJ2pZmK/0DLdCbivLDA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@nestjs/axios": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/@nestjs/axios/-/axios-3.1.1.tgz",
+ "integrity": "sha512-ySoxrzqX80P1q6LKLKGcgyBd2utg4gbC+4FsJNpXYvILorMlxss/ECNogD9EXLCE4JS5exVFD5ez0nK5hXcNTQ==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@nestjs/common": "^7.0.0 || ^8.0.0 || ^9.0.0 || ^10.0.0",
+ "axios": "^1.3.1",
+ "rxjs": "^6.0.0 || ^7.0.0"
+ }
+ },
+ "node_modules/@nestjs/common": {
+ "version": "10.4.6",
+ "resolved": "https://registry.npmjs.org/@nestjs/common/-/common-10.4.6.tgz",
+ "integrity": "sha512-KkezkZvU9poWaNq4L+lNvx+386hpOxPJkfXBBeSMrcqBOx8kVr36TGN2uYkF4Ta4zNu1KbCjmZbc0rhHSg296g==",
+ "license": "MIT",
+ "dependencies": {
+ "iterare": "1.2.1",
+ "tslib": "2.7.0",
+ "uid": "2.0.2"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/nest"
+ },
+ "peerDependencies": {
+ "class-transformer": "*",
+ "class-validator": "*",
+ "reflect-metadata": "^0.1.12 || ^0.2.0",
+ "rxjs": "^7.1.0"
+ },
+ "peerDependenciesMeta": {
+ "class-transformer": {
+ "optional": true
+ },
+ "class-validator": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@nestjs/common/node_modules/tslib": {
+ "version": "2.7.0",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz",
+ "integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==",
+ "license": "0BSD"
+ },
+ "node_modules/@nestjs/core": {
+ "version": "10.4.6",
+ "resolved": "https://registry.npmjs.org/@nestjs/core/-/core-10.4.6.tgz",
+ "integrity": "sha512-zXVPxCNRfO6gAy0yvEDjUxE/8gfZICJFpsl2lZAUH31bPb6m+tXuhUq2mVCTEltyMYQ+DYtRe+fEYM2v152N1g==",
+ "hasInstallScript": true,
+ "license": "MIT",
+ "dependencies": {
+ "@nuxtjs/opencollective": "0.3.2",
+ "fast-safe-stringify": "2.1.1",
+ "iterare": "1.2.1",
+ "path-to-regexp": "3.3.0",
+ "tslib": "2.7.0",
+ "uid": "2.0.2"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/nest"
+ },
+ "peerDependencies": {
+ "@nestjs/common": "^10.0.0",
+ "@nestjs/microservices": "^10.0.0",
+ "@nestjs/platform-express": "^10.0.0",
+ "@nestjs/websockets": "^10.0.0",
+ "reflect-metadata": "^0.1.12 || ^0.2.0",
+ "rxjs": "^7.1.0"
+ },
+ "peerDependenciesMeta": {
+ "@nestjs/microservices": {
+ "optional": true
+ },
+ "@nestjs/platform-express": {
+ "optional": true
+ },
+ "@nestjs/websockets": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@nestjs/core/node_modules/tslib": {
+ "version": "2.7.0",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz",
+ "integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==",
+ "license": "0BSD"
+ },
+ "node_modules/@nuxtjs/opencollective": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/@nuxtjs/opencollective/-/opencollective-0.3.2.tgz",
+ "integrity": "sha512-um0xL3fO7Mf4fDxcqx9KryrB7zgRM5JSlvGN5AGkP6JLM5XEKyjeAiPbNxdXVXQ16isuAhYpvP88NgL2BGd6aA==",
+ "license": "MIT",
+ "dependencies": {
+ "chalk": "^4.1.0",
+ "consola": "^2.15.0",
+ "node-fetch": "^2.6.1"
+ },
+ "bin": {
+ "opencollective": "bin/opencollective.js"
+ },
+ "engines": {
+ "node": ">=8.0.0",
+ "npm": ">=5.0.0"
+ }
+ },
+ "node_modules/@openapitools/openapi-generator-cli": {
+ "version": "2.15.3",
+ "resolved": "https://registry.npmjs.org/@openapitools/openapi-generator-cli/-/openapi-generator-cli-2.15.3.tgz",
+ "integrity": "sha512-2UBnsDlMt36thhdXxisbA1qReVtbCaw+NCvXoslRXlaJBL4qkAmZUhNeDLNu3LCbwA2PASMWhJSqeLwgwMCitw==",
+ "hasInstallScript": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@nestjs/axios": "3.1.1",
+ "@nestjs/common": "10.4.6",
+ "@nestjs/core": "10.4.6",
+ "@nuxtjs/opencollective": "0.3.2",
+ "axios": "1.7.7",
+ "chalk": "4.1.2",
+ "commander": "8.3.0",
+ "compare-versions": "4.1.4",
+ "concurrently": "6.5.1",
+ "console.table": "0.10.0",
+ "fs-extra": "10.1.0",
+ "glob": "9.3.5",
+ "inquirer": "8.2.6",
+ "lodash": "4.17.21",
+ "proxy-agent": "6.4.0",
+ "reflect-metadata": "0.1.13",
+ "rxjs": "7.8.1",
+ "tslib": "2.8.1"
+ },
+ "bin": {
+ "openapi-generator-cli": "main.js"
+ },
+ "engines": {
+ "node": ">=16"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/openapi_generator"
+ }
+ },
+ "node_modules/@smartrecruiters/openapi-first": {
+ "resolved": "../../node_modules/.pnpm/@smartrecruiters+openapi-first@1.2.0/node_modules/@smartrecruiters/openapi-first",
+ "link": true
+ },
+ "node_modules/@tootallnate/quickjs-emscripten": {
+ "version": "0.23.0",
+ "resolved": "https://registry.npmjs.org/@tootallnate/quickjs-emscripten/-/quickjs-emscripten-0.23.0.tgz",
+ "integrity": "sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==",
+ "license": "MIT"
+ },
+ "node_modules/@types/express": {
+ "resolved": "../../node_modules/.pnpm/@types+express@5.0.0/node_modules/@types/express",
+ "link": true
+ },
+ "node_modules/@types/node": {
+ "resolved": "../../node_modules/.pnpm/@types+node@22.10.0/node_modules/@types/node",
+ "link": true
+ },
+ "node_modules/@types/swagger-express-middleware": {
+ "resolved": "../../node_modules/.pnpm/@types+swagger-express-middleware@1.0.16/node_modules/@types/swagger-express-middleware",
+ "link": true
+ },
+ "node_modules/agent-base": {
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz",
+ "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==",
+ "license": "MIT",
+ "dependencies": {
+ "debug": "^4.3.4"
+ },
+ "engines": {
+ "node": ">= 14"
+ }
+ },
+ "node_modules/ansi-escapes": {
+ "version": "4.3.2",
+ "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz",
+ "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==",
+ "license": "MIT",
+ "dependencies": {
+ "type-fest": "^0.21.3"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/ansi-regex": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "license": "MIT",
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/ast-types": {
+ "version": "0.13.4",
+ "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.13.4.tgz",
+ "integrity": "sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==",
+ "license": "MIT",
+ "dependencies": {
+ "tslib": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/asynckit": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
+ "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
+ "license": "MIT"
+ },
+ "node_modules/axios": {
+ "version": "1.7.7",
+ "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.7.tgz",
+ "integrity": "sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q==",
+ "license": "MIT",
+ "dependencies": {
+ "follow-redirects": "^1.15.6",
+ "form-data": "^4.0.0",
+ "proxy-from-env": "^1.1.0"
+ }
+ },
+ "node_modules/balanced-match": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
+ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
+ "license": "MIT"
+ },
+ "node_modules/base64-js": {
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
+ "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/basic-ftp": {
+ "version": "5.0.5",
+ "resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.0.5.tgz",
+ "integrity": "sha512-4Bcg1P8xhUuqcii/S0Z9wiHIrQVPMermM1any+MX5GeGD7faD3/msQUDGLol9wOcz4/jbg/WJnGqoJF6LiBdtg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=10.0.0"
+ }
+ },
+ "node_modules/bl": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz",
+ "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==",
+ "license": "MIT",
+ "dependencies": {
+ "buffer": "^5.5.0",
+ "inherits": "^2.0.4",
+ "readable-stream": "^3.4.0"
+ }
+ },
+ "node_modules/brace-expansion": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
+ "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0"
+ }
+ },
+ "node_modules/buffer": {
+ "version": "5.7.1",
+ "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
+ "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "base64-js": "^1.3.1",
+ "ieee754": "^1.1.13"
+ }
+ },
+ "node_modules/chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/chardet": {
+ "version": "0.7.0",
+ "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz",
+ "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==",
+ "license": "MIT"
+ },
+ "node_modules/cli-cursor": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz",
+ "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==",
+ "license": "MIT",
+ "dependencies": {
+ "restore-cursor": "^3.1.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/cli-spinners": {
+ "version": "2.9.2",
+ "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz",
+ "integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/cli-width": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz",
+ "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==",
+ "license": "ISC",
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/cliui": {
+ "version": "7.0.4",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
+ "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==",
+ "license": "ISC",
+ "dependencies": {
+ "string-width": "^4.2.0",
+ "strip-ansi": "^6.0.0",
+ "wrap-ansi": "^7.0.0"
+ }
+ },
+ "node_modules/cliui/node_modules/wrap-ansi": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
+ "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^4.0.0",
+ "string-width": "^4.1.0",
+ "strip-ansi": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+ }
+ },
+ "node_modules/clone": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz",
+ "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.8"
+ }
+ },
+ "node_modules/color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "license": "MIT",
+ "dependencies": {
+ "color-name": "~1.1.4"
+ },
+ "engines": {
+ "node": ">=7.0.0"
+ }
+ },
+ "node_modules/color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "license": "MIT"
+ },
+ "node_modules/combined-stream": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
+ "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
+ "license": "MIT",
+ "dependencies": {
+ "delayed-stream": "~1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/commander": {
+ "version": "8.3.0",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz",
+ "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 12"
+ }
+ },
+ "node_modules/compare-versions": {
+ "version": "4.1.4",
+ "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-4.1.4.tgz",
+ "integrity": "sha512-FemMreK9xNyL8gQevsdRMrvO4lFCkQP7qbuktn1q8ndcNk1+0mz7lgE7b/sNvbhVgY4w6tMN1FDp6aADjqw2rw==",
+ "license": "MIT"
+ },
+ "node_modules/concurrently": {
+ "version": "6.5.1",
+ "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-6.5.1.tgz",
+ "integrity": "sha512-FlSwNpGjWQfRwPLXvJ/OgysbBxPkWpiVjy1042b0U7on7S7qwwMIILRj7WTN1mTgqa582bG6NFuScOoh6Zgdag==",
+ "license": "MIT",
+ "dependencies": {
+ "chalk": "^4.1.0",
+ "date-fns": "^2.16.1",
+ "lodash": "^4.17.21",
+ "rxjs": "^6.6.3",
+ "spawn-command": "^0.0.2-1",
+ "supports-color": "^8.1.0",
+ "tree-kill": "^1.2.2",
+ "yargs": "^16.2.0"
+ },
+ "bin": {
+ "concurrently": "bin/concurrently.js"
+ },
+ "engines": {
+ "node": ">=10.0.0"
+ }
+ },
+ "node_modules/concurrently/node_modules/rxjs": {
+ "version": "6.6.7",
+ "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz",
+ "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "tslib": "^1.9.0"
+ },
+ "engines": {
+ "npm": ">=2.0.0"
+ }
+ },
+ "node_modules/concurrently/node_modules/supports-color": {
+ "version": "8.1.1",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
+ "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
+ "license": "MIT",
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/supports-color?sponsor=1"
+ }
+ },
+ "node_modules/concurrently/node_modules/tslib": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
+ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
+ "license": "0BSD"
+ },
+ "node_modules/consola": {
+ "version": "2.15.3",
+ "resolved": "https://registry.npmjs.org/consola/-/consola-2.15.3.tgz",
+ "integrity": "sha512-9vAdYbHj6x2fLKC4+oPH0kFzY/orMZyG2Aj+kNylHxKGJ/Ed4dpNyAQYwJOdqO4zdM7XpVHmyejQDcQHrnuXbw==",
+ "license": "MIT"
+ },
+ "node_modules/console.table": {
+ "version": "0.10.0",
+ "resolved": "https://registry.npmjs.org/console.table/-/console.table-0.10.0.tgz",
+ "integrity": "sha512-dPyZofqggxuvSf7WXvNjuRfnsOk1YazkVP8FdxH4tcH2c37wc79/Yl6Bhr7Lsu00KMgy2ql/qCMuNu8xctZM8g==",
+ "license": "MIT",
+ "dependencies": {
+ "easy-table": "1.1.0"
+ },
+ "engines": {
+ "node": "> 0.10"
+ }
+ },
+ "node_modules/data-uri-to-buffer": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-6.0.2.tgz",
+ "integrity": "sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 14"
+ }
+ },
+ "node_modules/date-fns": {
+ "version": "2.30.0",
+ "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.30.0.tgz",
+ "integrity": "sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/runtime": "^7.21.0"
+ },
+ "engines": {
+ "node": ">=0.11"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/date-fns"
+ }
+ },
+ "node_modules/debug": {
+ "version": "4.3.7",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
+ "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.3"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/defaults": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz",
+ "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==",
+ "license": "MIT",
+ "dependencies": {
+ "clone": "^1.0.2"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/degenerator": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-5.0.1.tgz",
+ "integrity": "sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==",
+ "license": "MIT",
+ "dependencies": {
+ "ast-types": "^0.13.4",
+ "escodegen": "^2.1.0",
+ "esprima": "^4.0.1"
+ },
+ "engines": {
+ "node": ">= 14"
+ }
+ },
+ "node_modules/delayed-stream": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
+ "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/easy-table": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/easy-table/-/easy-table-1.1.0.tgz",
+ "integrity": "sha512-oq33hWOSSnl2Hoh00tZWaIPi1ievrD9aFG82/IgjlycAnW9hHx5PkJiXpxPsgEE+H7BsbVQXFVFST8TEXS6/pA==",
+ "license": "MIT",
+ "optionalDependencies": {
+ "wcwidth": ">=1.0.1"
+ }
+ },
+ "node_modules/emoji-regex": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+ "license": "MIT"
+ },
+ "node_modules/escalade": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
+ "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/escape-string-regexp": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+ "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
+ "node_modules/escodegen": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz",
+ "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==",
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "esprima": "^4.0.1",
+ "estraverse": "^5.2.0",
+ "esutils": "^2.0.2"
+ },
+ "bin": {
+ "escodegen": "bin/escodegen.js",
+ "esgenerate": "bin/esgenerate.js"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "optionalDependencies": {
+ "source-map": "~0.6.1"
+ }
+ },
+ "node_modules/esprima": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
+ "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
+ "license": "BSD-2-Clause",
+ "bin": {
+ "esparse": "bin/esparse.js",
+ "esvalidate": "bin/esvalidate.js"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/estraverse": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
+ "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/esutils": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
+ "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/express": {
+ "resolved": "../../node_modules/.pnpm/express@4.21.1/node_modules/express",
+ "link": true
+ },
+ "node_modules/external-editor": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz",
+ "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==",
+ "license": "MIT",
+ "dependencies": {
+ "chardet": "^0.7.0",
+ "iconv-lite": "^0.4.24",
+ "tmp": "^0.0.33"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/fast-safe-stringify": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz",
+ "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==",
+ "license": "MIT"
+ },
+ "node_modules/figures": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz",
+ "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==",
+ "license": "MIT",
+ "dependencies": {
+ "escape-string-regexp": "^1.0.5"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/follow-redirects": {
+ "version": "1.15.9",
+ "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz",
+ "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://github.com/sponsors/RubenVerborgh"
+ }
+ ],
+ "license": "MIT",
+ "engines": {
+ "node": ">=4.0"
+ },
+ "peerDependenciesMeta": {
+ "debug": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/form-data": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.1.tgz",
+ "integrity": "sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==",
+ "license": "MIT",
+ "dependencies": {
+ "asynckit": "^0.4.0",
+ "combined-stream": "^1.0.8",
+ "mime-types": "^2.1.12"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/fs-extra": {
+ "version": "10.1.0",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz",
+ "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==",
+ "license": "MIT",
+ "dependencies": {
+ "graceful-fs": "^4.2.0",
+ "jsonfile": "^6.0.1",
+ "universalify": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/fs.realpath": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+ "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
+ "license": "ISC"
+ },
+ "node_modules/get-caller-file": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
+ "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
+ "license": "ISC",
+ "engines": {
+ "node": "6.* || 8.* || >= 10.*"
+ }
+ },
+ "node_modules/get-uri": {
+ "version": "6.0.3",
+ "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-6.0.3.tgz",
+ "integrity": "sha512-BzUrJBS9EcUb4cFol8r4W3v1cPsSyajLSthNkz5BxbpDcHN5tIrM10E2eNvfnvBn3DaT3DUgx0OpsBKkaOpanw==",
+ "license": "MIT",
+ "dependencies": {
+ "basic-ftp": "^5.0.2",
+ "data-uri-to-buffer": "^6.0.2",
+ "debug": "^4.3.4",
+ "fs-extra": "^11.2.0"
+ },
+ "engines": {
+ "node": ">= 14"
+ }
+ },
+ "node_modules/get-uri/node_modules/fs-extra": {
+ "version": "11.2.0",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz",
+ "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==",
+ "license": "MIT",
+ "dependencies": {
+ "graceful-fs": "^4.2.0",
+ "jsonfile": "^6.0.1",
+ "universalify": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=14.14"
+ }
+ },
+ "node_modules/glob": {
+ "version": "9.3.5",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-9.3.5.tgz",
+ "integrity": "sha512-e1LleDykUz2Iu+MTYdkSsuWX8lvAjAcs0Xef0lNIu0S2wOAzuTxCJtcd9S3cijlwYF18EsU3rzb8jPVobxDh9Q==",
+ "license": "ISC",
+ "dependencies": {
+ "fs.realpath": "^1.0.0",
+ "minimatch": "^8.0.2",
+ "minipass": "^4.2.4",
+ "path-scurry": "^1.6.1"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/graceful-fs": {
+ "version": "4.2.11",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
+ "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
+ "license": "ISC"
+ },
+ "node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/http-proxy-agent": {
+ "version": "7.0.2",
+ "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz",
+ "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==",
+ "license": "MIT",
+ "dependencies": {
+ "agent-base": "^7.1.0",
+ "debug": "^4.3.4"
+ },
+ "engines": {
+ "node": ">= 14"
+ }
+ },
+ "node_modules/https-proxy-agent": {
+ "version": "7.0.5",
+ "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz",
+ "integrity": "sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==",
+ "license": "MIT",
+ "dependencies": {
+ "agent-base": "^7.0.2",
+ "debug": "4"
+ },
+ "engines": {
+ "node": ">= 14"
+ }
+ },
+ "node_modules/iconv-lite": {
+ "version": "0.4.24",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
+ "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
+ "license": "MIT",
+ "dependencies": {
+ "safer-buffer": ">= 2.1.2 < 3"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ieee754": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
+ "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/inherits": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
+ "license": "ISC"
+ },
+ "node_modules/inquirer": {
+ "version": "8.2.6",
+ "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-8.2.6.tgz",
+ "integrity": "sha512-M1WuAmb7pn9zdFRtQYk26ZBoY043Sse0wVDdk4Bppr+JOXyQYybdtvK+l9wUibhtjdjvtoiNy8tk+EgsYIUqKg==",
+ "license": "MIT",
+ "dependencies": {
+ "ansi-escapes": "^4.2.1",
+ "chalk": "^4.1.1",
+ "cli-cursor": "^3.1.0",
+ "cli-width": "^3.0.0",
+ "external-editor": "^3.0.3",
+ "figures": "^3.0.0",
+ "lodash": "^4.17.21",
+ "mute-stream": "0.0.8",
+ "ora": "^5.4.1",
+ "run-async": "^2.4.0",
+ "rxjs": "^7.5.5",
+ "string-width": "^4.1.0",
+ "strip-ansi": "^6.0.0",
+ "through": "^2.3.6",
+ "wrap-ansi": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=12.0.0"
+ }
+ },
+ "node_modules/ip-address": {
+ "version": "9.0.5",
+ "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-9.0.5.tgz",
+ "integrity": "sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==",
+ "license": "MIT",
+ "dependencies": {
+ "jsbn": "1.1.0",
+ "sprintf-js": "^1.1.3"
+ },
+ "engines": {
+ "node": ">= 12"
+ }
+ },
+ "node_modules/is-fullwidth-code-point": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/is-interactive": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz",
+ "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/is-unicode-supported": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz",
+ "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/iterare": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/iterare/-/iterare-1.2.1.tgz",
+ "integrity": "sha512-RKYVTCjAnRthyJes037NX/IiqeidgN1xc3j1RjFfECFp28A1GVwK9nA+i0rJPaHqSZwygLzRnFlzUuHFoWWy+Q==",
+ "license": "ISC",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/jsbn": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz",
+ "integrity": "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==",
+ "license": "MIT"
+ },
+ "node_modules/jsonfile": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz",
+ "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==",
+ "license": "MIT",
+ "dependencies": {
+ "universalify": "^2.0.0"
+ },
+ "optionalDependencies": {
+ "graceful-fs": "^4.1.6"
+ }
+ },
+ "node_modules/lodash": {
+ "version": "4.17.21",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
+ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
+ "license": "MIT"
+ },
+ "node_modules/log-symbols": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz",
+ "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==",
+ "license": "MIT",
+ "dependencies": {
+ "chalk": "^4.1.0",
+ "is-unicode-supported": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/lru-cache": {
+ "version": "10.4.3",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
+ "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==",
+ "license": "ISC"
+ },
+ "node_modules/mime-db": {
+ "version": "1.52.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
+ "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/mime-types": {
+ "version": "2.1.35",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
+ "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
+ "license": "MIT",
+ "dependencies": {
+ "mime-db": "1.52.0"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/mimic-fn": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
+ "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/minimatch": {
+ "version": "8.0.4",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-8.0.4.tgz",
+ "integrity": "sha512-W0Wvr9HyFXZRGIDgCicunpQ299OKXs9RgZfaukz4qAW/pJhcpUfupc9c+OObPOFueNy8VSrZgEmDtk6Kh4WzDA==",
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/minipass": {
+ "version": "4.2.8",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-4.2.8.tgz",
+ "integrity": "sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ==",
+ "license": "ISC",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+ "license": "MIT"
+ },
+ "node_modules/mute-stream": {
+ "version": "0.0.8",
+ "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz",
+ "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==",
+ "license": "ISC"
+ },
+ "node_modules/netmask": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/netmask/-/netmask-2.0.2.tgz",
+ "integrity": "sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4.0"
+ }
+ },
+ "node_modules/node-fetch": {
+ "version": "2.7.0",
+ "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
+ "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==",
+ "license": "MIT",
+ "dependencies": {
+ "whatwg-url": "^5.0.0"
+ },
+ "engines": {
+ "node": "4.x || >=6.0.0"
+ },
+ "peerDependencies": {
+ "encoding": "^0.1.0"
+ },
+ "peerDependenciesMeta": {
+ "encoding": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/onetime": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
+ "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
+ "license": "MIT",
+ "dependencies": {
+ "mimic-fn": "^2.1.0"
+ },
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/ora": {
+ "version": "5.4.1",
+ "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz",
+ "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==",
+ "license": "MIT",
+ "dependencies": {
+ "bl": "^4.1.0",
+ "chalk": "^4.1.0",
+ "cli-cursor": "^3.1.0",
+ "cli-spinners": "^2.5.0",
+ "is-interactive": "^1.0.0",
+ "is-unicode-supported": "^0.1.0",
+ "log-symbols": "^4.1.0",
+ "strip-ansi": "^6.0.0",
+ "wcwidth": "^1.0.1"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/os-tmpdir": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
+ "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/pac-proxy-agent": {
+ "version": "7.0.2",
+ "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-7.0.2.tgz",
+ "integrity": "sha512-BFi3vZnO9X5Qt6NRz7ZOaPja3ic0PhlsmCRYLOpN11+mWBCR6XJDqW5RF3j8jm4WGGQZtBA+bTfxYzeKW73eHg==",
+ "license": "MIT",
+ "dependencies": {
+ "@tootallnate/quickjs-emscripten": "^0.23.0",
+ "agent-base": "^7.0.2",
+ "debug": "^4.3.4",
+ "get-uri": "^6.0.1",
+ "http-proxy-agent": "^7.0.0",
+ "https-proxy-agent": "^7.0.5",
+ "pac-resolver": "^7.0.1",
+ "socks-proxy-agent": "^8.0.4"
+ },
+ "engines": {
+ "node": ">= 14"
+ }
+ },
+ "node_modules/pac-resolver": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-7.0.1.tgz",
+ "integrity": "sha512-5NPgf87AT2STgwa2ntRMr45jTKrYBGkVU36yT0ig/n/GMAa3oPqhZfIQ2kMEimReg0+t9kZViDVZ83qfVUlckg==",
+ "license": "MIT",
+ "dependencies": {
+ "degenerator": "^5.0.0",
+ "netmask": "^2.0.2"
+ },
+ "engines": {
+ "node": ">= 14"
+ }
+ },
+ "node_modules/path-scurry": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz",
+ "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==",
+ "license": "BlueOak-1.0.0",
+ "dependencies": {
+ "lru-cache": "^10.2.0",
+ "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/path-scurry/node_modules/minipass": {
+ "version": "7.1.2",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz",
+ "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==",
+ "license": "ISC",
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ }
+ },
+ "node_modules/path-to-regexp": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-3.3.0.tgz",
+ "integrity": "sha512-qyCH421YQPS2WFDxDjftfc1ZR5WKQzVzqsp4n9M2kQhVOo/ByahFoUNJfl58kOcEGfQ//7weFTDhm+ss8Ecxgw==",
+ "license": "MIT"
+ },
+ "node_modules/proxy-agent": {
+ "version": "6.4.0",
+ "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-6.4.0.tgz",
+ "integrity": "sha512-u0piLU+nCOHMgGjRbimiXmA9kM/L9EHh3zL81xCdp7m+Y2pHIsnmbdDoEDoAz5geaonNR6q6+yOPQs6n4T6sBQ==",
+ "license": "MIT",
+ "dependencies": {
+ "agent-base": "^7.0.2",
+ "debug": "^4.3.4",
+ "http-proxy-agent": "^7.0.1",
+ "https-proxy-agent": "^7.0.3",
+ "lru-cache": "^7.14.1",
+ "pac-proxy-agent": "^7.0.1",
+ "proxy-from-env": "^1.1.0",
+ "socks-proxy-agent": "^8.0.2"
+ },
+ "engines": {
+ "node": ">= 14"
+ }
+ },
+ "node_modules/proxy-agent/node_modules/lru-cache": {
+ "version": "7.18.3",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz",
+ "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==",
+ "license": "ISC",
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/proxy-from-env": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
+ "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==",
+ "license": "MIT"
+ },
+ "node_modules/readable-stream": {
+ "version": "3.6.2",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
+ "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
+ "license": "MIT",
+ "dependencies": {
+ "inherits": "^2.0.3",
+ "string_decoder": "^1.1.1",
+ "util-deprecate": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/reflect-metadata": {
+ "version": "0.1.13",
+ "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.13.tgz",
+ "integrity": "sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==",
+ "license": "Apache-2.0"
+ },
+ "node_modules/regenerator-runtime": {
+ "version": "0.14.1",
+ "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz",
+ "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==",
+ "license": "MIT"
+ },
+ "node_modules/require-directory": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
+ "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/restore-cursor": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz",
+ "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==",
+ "license": "MIT",
+ "dependencies": {
+ "onetime": "^5.1.0",
+ "signal-exit": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/run-async": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz",
+ "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.12.0"
+ }
+ },
+ "node_modules/rxjs": {
+ "version": "7.8.1",
+ "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz",
+ "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "tslib": "^2.1.0"
+ }
+ },
+ "node_modules/safe-buffer": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/safer-buffer": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
+ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
+ "license": "MIT"
+ },
+ "node_modules/signal-exit": {
+ "version": "3.0.7",
+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
+ "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==",
+ "license": "ISC"
+ },
+ "node_modules/smart-buffer": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz",
+ "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 6.0.0",
+ "npm": ">= 3.0.0"
+ }
+ },
+ "node_modules/socks": {
+ "version": "2.8.3",
+ "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.3.tgz",
+ "integrity": "sha512-l5x7VUUWbjVFbafGLxPWkYsHIhEvmF85tbIeFZWc8ZPtoMyybuEhL7Jye/ooC4/d48FgOjSJXgsF/AJPYCW8Zw==",
+ "license": "MIT",
+ "dependencies": {
+ "ip-address": "^9.0.5",
+ "smart-buffer": "^4.2.0"
+ },
+ "engines": {
+ "node": ">= 10.0.0",
+ "npm": ">= 3.0.0"
+ }
+ },
+ "node_modules/socks-proxy-agent": {
+ "version": "8.0.4",
+ "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.4.tgz",
+ "integrity": "sha512-GNAq/eg8Udq2x0eNiFkr9gRg5bA7PXEWagQdeRX4cPSG+X/8V38v637gim9bjFptMk1QWsCTr0ttrJEiXbNnRw==",
+ "license": "MIT",
+ "dependencies": {
+ "agent-base": "^7.1.1",
+ "debug": "^4.3.4",
+ "socks": "^2.8.3"
+ },
+ "engines": {
+ "node": ">= 14"
+ }
+ },
+ "node_modules/source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "license": "BSD-3-Clause",
+ "optional": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/spawn-command": {
+ "version": "0.0.2",
+ "resolved": "https://registry.npmjs.org/spawn-command/-/spawn-command-0.0.2.tgz",
+ "integrity": "sha512-zC8zGoGkmc8J9ndvml8Xksr1Amk9qBujgbF0JAIWO7kXr43w0h/0GJNM/Vustixu+YE8N/MTrQ7N31FvHUACxQ=="
+ },
+ "node_modules/sprintf-js": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz",
+ "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==",
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/string_decoder": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
+ "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
+ "license": "MIT",
+ "dependencies": {
+ "safe-buffer": "~5.2.0"
+ }
+ },
+ "node_modules/string-width": {
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+ "license": "MIT",
+ "dependencies": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/strip-ansi": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "license": "MIT",
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/swagger-typescript-codegen": {
+ "resolved": "../../node_modules/.pnpm/swagger-typescript-codegen@3.2.4/node_modules/swagger-typescript-codegen",
+ "link": true
+ },
+ "node_modules/through": {
+ "version": "2.3.8",
+ "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
+ "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==",
+ "license": "MIT"
+ },
+ "node_modules/tmp": {
+ "version": "0.0.33",
+ "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
+ "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==",
+ "license": "MIT",
+ "dependencies": {
+ "os-tmpdir": "~1.0.2"
+ },
+ "engines": {
+ "node": ">=0.6.0"
+ }
+ },
+ "node_modules/tr46": {
+ "version": "0.0.3",
+ "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
+ "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==",
+ "license": "MIT"
+ },
+ "node_modules/tree-kill": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz",
+ "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==",
+ "license": "MIT",
+ "bin": {
+ "tree-kill": "cli.js"
+ }
+ },
+ "node_modules/tslib": {
+ "version": "2.8.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
+ "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
+ "license": "0BSD"
+ },
+ "node_modules/type-fest": {
+ "version": "0.21.3",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz",
+ "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==",
+ "license": "(MIT OR CC0-1.0)",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/typescript": {
+ "resolved": "../../node_modules/.pnpm/typescript@5.7.2/node_modules/typescript",
+ "link": true
+ },
+ "node_modules/uid": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/uid/-/uid-2.0.2.tgz",
+ "integrity": "sha512-u3xV3X7uzvi5b1MncmZo3i2Aw222Zk1keqLA1YkHldREkAhAqi65wuPfe7lHx8H/Wzy+8CE7S7uS3jekIM5s8g==",
+ "license": "MIT",
+ "dependencies": {
+ "@lukeed/csprng": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/universalify": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz",
+ "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 10.0.0"
+ }
+ },
+ "node_modules/util-deprecate": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
+ "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
+ "license": "MIT"
+ },
+ "node_modules/wcwidth": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz",
+ "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==",
+ "license": "MIT",
+ "dependencies": {
+ "defaults": "^1.0.3"
+ }
+ },
+ "node_modules/webidl-conversions": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
+ "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==",
+ "license": "BSD-2-Clause"
+ },
+ "node_modules/whatwg-url": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
+ "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
+ "license": "MIT",
+ "dependencies": {
+ "tr46": "~0.0.3",
+ "webidl-conversions": "^3.0.0"
+ }
+ },
+ "node_modules/wrap-ansi": {
+ "version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz",
+ "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==",
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^4.0.0",
+ "string-width": "^4.1.0",
+ "strip-ansi": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/y18n": {
+ "version": "5.0.8",
+ "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
+ "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
+ "license": "ISC",
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/yargs": {
+ "version": "16.2.0",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz",
+ "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==",
+ "license": "MIT",
+ "dependencies": {
+ "cliui": "^7.0.2",
+ "escalade": "^3.1.1",
+ "get-caller-file": "^2.0.5",
+ "require-directory": "^2.1.1",
+ "string-width": "^4.2.0",
+ "y18n": "^5.0.5",
+ "yargs-parser": "^20.2.2"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/yargs-parser": {
+ "version": "20.2.9",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz",
+ "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==",
+ "license": "ISC",
+ "engines": {
+ "node": ">=10"
+ }
+ }
+ }
+}
diff --git a/helpers/wormholescanMock/package.json b/helpers/wormholescanMock/package.json
new file mode 100644
index 0000000000..fa84372447
--- /dev/null
+++ b/helpers/wormholescanMock/package.json
@@ -0,0 +1,31 @@
+{
+ "name": "wormholescan-mock",
+ "version": "1.0.0",
+ "main": "dist/index.js",
+ "scripts": {
+ "test": "echo \"Error: no test specified\" && exit 1",
+ "generate-types": "openapi-generator-cli generate --generator-key typescript-fetch",
+ "start": "node dist/index.js",
+ "dev": "nodemon src/index.ts"
+ },
+ "author": "",
+ "license": "ISC",
+ "dependencies": {
+ "@openapitools/openapi-generator-cli": "^2.15.3",
+ "dotenv": "^8.0.0",
+ "ethers": "^5.7.2",
+ "ethers-types": "^3.17.3",
+ "express": "^4.21.1",
+ "openapi-generator": "^0.1.39",
+ "swagger-typescript-codegen": "^3.2.4"
+ },
+ "devDependencies": {
+ "@types/express": "^5.0.0",
+ "@types/node": "^22.10.0",
+ "concurrently": "^9.1.0",
+ "nodemon": "^3.1.7",
+ "ts-node": "^9.1.1",
+ "typescript": "^5.7.2"
+ },
+ "description": ""
+}
diff --git a/helpers/wormholescanMock/src/encodeMockVAA.ts b/helpers/wormholescanMock/src/encodeMockVAA.ts
new file mode 100644
index 0000000000..0316a3c16c
--- /dev/null
+++ b/helpers/wormholescanMock/src/encodeMockVAA.ts
@@ -0,0 +1,36 @@
+import { ethers, Contract } from "ethers";
+
+function ethereumAddressToWormholeAddress(address: string) {
+ return ethers.utils.hexZeroPad(ethers.utils.hexStripZeros(ethers.utils.hexlify(address)), 32);
+}
+
+export default async function encodeMockVAA(
+ sender: string,
+ sequence: number,
+ nonce: number,
+ payload: string,
+ consistencyLevel: number,
+ chainId: number,
+ homeBridgeAddress: string,
+ homeBridgeProvider: ethers.providers.Provider,
+) {
+ const homeBridge = new Contract(
+ homeBridgeAddress,
+ ["function buildVAABody(uint32,uint32,uint16,bytes32,uint64,uint8,bytes) view returns(bytes)"],
+ homeBridgeProvider,
+ );
+ const timestamp = Math.floor(Date.now() / 1000);
+ const emitterChainId = chainId;
+ const emitterAddress = ethereumAddressToWormholeAddress(sender);
+
+ const vaaBody = await homeBridge.buildVAABody(timestamp, nonce, emitterChainId, emitterAddress, sequence, consistencyLevel, payload);
+
+ const vaaHeader =
+ "0x01" + // version
+ "00000000" + // guardianSetIndex
+ "01" + // signature count
+ "01" + // signature index
+ "7777000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007777";
+
+ return vaaHeader + vaaBody.toString("hex").slice(2);
+}
diff --git a/helpers/wormholescanMock/src/index.ts b/helpers/wormholescanMock/src/index.ts
new file mode 100644
index 0000000000..36c38423da
--- /dev/null
+++ b/helpers/wormholescanMock/src/index.ts
@@ -0,0 +1,220 @@
+import express, { Express, Request, Response } from "express";
+import { LogDescription } from "ethers/lib/utils";
+import { ethers } from "ethers";
+import { OperationsOperationResponse, VaaChainID } from "../openapi-generated-types/models";
+import encodeMockVAA from "./encodeMockVAA";
+
+const app: Express = express();
+const port = process.env.PORT || 3000;
+const providerURLs: string[] = process.env.PROVIDER_URLS ? process.env.PROVIDER_URLS.split(",") : [];
+
+const providers: ethers.providers.JsonRpcProvider[] = [];
+
+function wormholeAddressToEvmAddress(address: string): string {
+ return ethers.utils.getAddress(`0x${address.slice(26, 66)}`);
+}
+
+function evmChainIdToWormholeChainId(chainId: number) {
+ // So I've decreed that for chainId 265669100, we use 10003 (which is really arbitrum sepolia)
+ // and for chainId 265669101, we use 10002 (which is really sepolia).
+
+ switch (chainId) {
+ case 265669100:
+ return 10003;
+ case 265669101:
+ return 10002;
+ case 265669102:
+ return 10004;
+ default:
+ throw new Error("Invalid chainId");
+ }
+}
+
+type LogAndEvent = {
+ log: ethers.providers.Log;
+ event: LogDescription;
+ chainId?: VaaChainID;
+};
+
+async function getLogMessagePublishedForVAA(
+ provider: ethers.providers.Provider,
+ emitterWormholeChainId: number,
+ wormholeSender: string,
+ sequence: string,
+): Promise {
+ const providerChainId = (await provider.getNetwork()).chainId;
+ const providerWormholeChainId = await evmChainIdToWormholeChainId(providerChainId);
+ if (providerWormholeChainId !== emitterWormholeChainId) {
+ return;
+ }
+ const logs = await provider.getLogs({
+ topics: [ethers.utils.id("LogMessagePublished(address,uint64,uint32,bytes,uint8)"), wormholeSender],
+ fromBlock: 1,
+ });
+
+ if (logs.length === 0) {
+ return;
+ }
+
+ const wormhole = new ethers.Contract(
+ logs[0].address,
+ ["event LogMessagePublished(address indexed sender,uint64 sequence,uint32 nonce,bytes payload,uint8 consistencyLevel)"],
+ provider,
+ );
+
+ const logsAndEvents = logs.map((log) => {
+ return { log, event: wormhole.interface.parseLog(log) } as LogAndEvent;
+ });
+
+ const filteredLogsAndEvents = logsAndEvents.filter(
+ (logAndEvent) =>
+ logAndEvent.event.args.sequence.toString() === sequence &&
+ ethers.utils.getAddress(logAndEvent.event.args.sender) === wormholeAddressToEvmAddress(wormholeSender),
+ );
+
+ if (filteredLogsAndEvents.length === 0) {
+ return;
+ }
+ const requestingEventAndLog = filteredLogsAndEvents[0];
+
+ const { chainId } = await provider.getNetwork();
+ requestingEventAndLog.chainId = evmChainIdToWormholeChainId(chainId);
+ return requestingEventAndLog; // eslint-disable-line consistent-return
+}
+
+async function getColonyReceivingTransaction(
+ provider: ethers.providers.Provider,
+ emitterWormholeChainId: number,
+ emitterWormholeAddress: string,
+ sequence: string,
+): Promise {
+ const logs = await provider.getLogs({
+ topics: [ethers.utils.id("WormholeMessageReceived(uint16,bytes32,uint64)")],
+ });
+
+ if (logs.length === 0) {
+ return;
+ }
+ const wormhole = new ethers.Contract(
+ logs[0].address,
+ ["event WormholeMessageReceived(uint16 emitterChainId, bytes32 emitterAddress, uint64 sequence)"],
+ provider,
+ );
+
+ const logsAndEvents = logs.map((log) => {
+ return { log, event: wormhole.interface.parseLog(log) } as LogAndEvent;
+ });
+
+ const filteredLogsAndEvents = logsAndEvents.filter(
+ (logAndEvent: LogAndEvent) =>
+ logAndEvent.event.args?.sequence.toString() === sequence &&
+ logsAndEvents[0].event.args.emitterAddress === emitterWormholeAddress &&
+ logAndEvent.event.args?.emitterChainId === emitterWormholeChainId,
+ );
+
+ if (filteredLogsAndEvents.length === 0) {
+ return;
+ }
+ const receivingEventAndLog = filteredLogsAndEvents[0];
+
+ const { chainId } = await provider.getNetwork();
+ const wormholeChainId = await evmChainIdToWormholeChainId(chainId);
+ receivingEventAndLog.chainId = wormholeChainId;
+ return receivingEventAndLog; // eslint-disable-line consistent-return
+}
+
+app.get("/api/v1/operations/:chain/:emitter/:sequence", async (req: Request, res: Response) => {
+ // TODO: get provider based on :chain
+ // Emitter must be a valid _Wormhole_ address
+ // Which is length 64 and valid hex
+ let emitterAddress = req.params.emitter;
+ if (req.params.emitter.substring(0, 2) !== "0x") {
+ emitterAddress = `0x${req.params.emitter}`;
+ }
+ emitterAddress = emitterAddress.toLowerCase();
+ if (!ethers.utils.isHexString(emitterAddress) || emitterAddress.length !== 66) {
+ res.status(400).send({
+ code: 3,
+ message: "MALFORMED EMITTER_ADDR",
+ });
+ return;
+ }
+
+ let requestingEventAndLog;
+ let relevantProvider;
+ for (const provider of providers) {
+ requestingEventAndLog = await getLogMessagePublishedForVAA(provider, parseInt(req.params.chain, 10), emitterAddress, req.params.sequence);
+ if (requestingEventAndLog) {
+ relevantProvider = provider;
+ break;
+ }
+ }
+
+ if (!requestingEventAndLog) {
+ res.status(404).send({
+ code: 1,
+ message: "VAA NOT FOUND",
+ });
+ return;
+ }
+
+ let receivingEventAndLog;
+ for (const provider of providers) {
+ receivingEventAndLog = await getColonyReceivingTransaction(provider, parseInt(req.params.chain, 10), emitterAddress, req.params.sequence);
+ if (receivingEventAndLog) {
+ break;
+ }
+ }
+
+ const body: OperationsOperationResponse = {
+ id: `${req.params.chain}/${req.params.emitter}/${req.params.sequence}`,
+ sourceChain: {
+ chainId: requestingEventAndLog.chainId,
+ transaction: {
+ txHash: requestingEventAndLog.log.transactionHash,
+ },
+ status: "confirmed",
+ },
+ };
+
+ const signed = true;
+ if (signed) {
+ const rawVAA = await encodeMockVAA(
+ emitterAddress,
+ parseInt(req.params.sequence, 10),
+ 0,
+ requestingEventAndLog.event.args.payload,
+ 0,
+ parseInt(req.params.chain, 10),
+ requestingEventAndLog.log.address,
+ relevantProvider,
+ );
+ body.vaa = { raw: rawVAA };
+ }
+
+ if (receivingEventAndLog) {
+ body.targetChain = {
+ chainId: receivingEventAndLog.chainId,
+ transaction: {
+ txHash: receivingEventAndLog.log.transactionHash,
+ },
+ status: "confirmed",
+ };
+ }
+
+ res.send(body);
+});
+
+app.listen(port, async () => {
+ for (const providerURL of providerURLs) {
+ const p = new ethers.providers.JsonRpcProvider(providerURL);
+ try {
+ await p.getNetwork();
+ providers.push(p);
+ } catch (e) {
+ console.error(`Failed to connect to provider ${providerURL} with error ${e}, skipping`);
+ }
+ }
+
+ console.log(`[server]: Server is running at http://localhost:${port}`);
+});
diff --git a/helpers/wormholescanMock/swagger.json b/helpers/wormholescanMock/swagger.json
new file mode 100644
index 0000000000..1985772fb3
--- /dev/null
+++ b/helpers/wormholescanMock/swagger.json
@@ -0,0 +1,4484 @@
+{
+ "swagger": "2.0",
+ "info": {
+ "description": "Wormhole Guardian API\nThis is the API for the Wormhole Guardian and Explorer.\nThe API has two namespaces: wormholescan and guardian.\nwormholescan is the namespace for the explorer and the new endpoints. The prefix is /api/v1.\nguardian is the legacy namespace backguard compatible with guardian node API. The prefix is /v1.\nThis API is public and does not require authentication although some endpoints are rate limited.\nCheck each endpoint documentation for more information.",
+ "title": "Wormholescan API",
+ "termsOfService": "https://wormhole.com/",
+ "contact": {
+ "name": "API Support",
+ "url": "https://discord.com/invite/wormholecrypto",
+ "email": "info@wormhole.com"
+ },
+ "license": {
+ "name": "Apache 2.0",
+ "url": "http://www.apache.org/licenses/LICENSE-2.0.html"
+ },
+ "version": "1.0"
+ },
+ "basePath": "/",
+ "paths": {
+ "/api/v1/address/:address": {
+ "get": {
+ "description": "Lookup an address",
+ "tags": [
+ "wormholescan"
+ ],
+ "operationId": "find-address-by-id",
+ "parameters": [
+ {
+ "type": "string",
+ "description": "address",
+ "name": "address",
+ "in": "path",
+ "required": true
+ },
+ {
+ "type": "integer",
+ "description": "Page number. Starts at 0.",
+ "name": "page",
+ "in": "query"
+ },
+ {
+ "type": "integer",
+ "description": "Number of elements per page.",
+ "name": "pageSize",
+ "in": "query"
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "OK",
+ "schema": {
+ "$ref": "#/definitions/response.Response-address_AddressOverview"
+ }
+ },
+ "400": {
+ "description": "Bad Request"
+ },
+ "404": {
+ "description": "Not Found"
+ },
+ "500": {
+ "description": "Internal Server Error"
+ }
+ }
+ }
+ },
+ "/api/v1/application-activity": {
+ "get": {
+ "description": "Search for a specific period of time the number of transactions and the volume per application.",
+ "tags": [
+ "wormholescan"
+ ],
+ "operationId": "application-activity",
+ "parameters": [
+ {
+ "type": "string",
+ "description": "Time span, supported values: 1d, 1mo and 1y",
+ "name": "timespan",
+ "in": "query",
+ "required": true
+ },
+ {
+ "type": "string",
+ "description": "From date, supported format 2006-01-02T15:04:05Z07:00",
+ "name": "from",
+ "in": "query",
+ "required": true
+ },
+ {
+ "type": "string",
+ "description": "To date, supported format 2006-01-02T15:04:05Z07:00",
+ "name": "to",
+ "in": "query",
+ "required": true
+ },
+ {
+ "type": "string",
+ "description": "Search by appId",
+ "name": "appIds",
+ "in": "query"
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "OK",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/transactions.ChainActivityTopResult"
+ }
+ }
+ },
+ "400": {
+ "description": "Bad Request"
+ },
+ "500": {
+ "description": "Internal Server Error"
+ }
+ }
+ }
+ },
+ "/api/v1/global-tx/:chain_id/:emitter/:seq": {
+ "get": {
+ "description": "Find a global transaction by VAA ID\nGlobal transactions is a logical association of two transactions that are related to each other by a unique VAA ID.\nThe first transaction is created on the origin chain when the VAA is emitted.\nThe second transaction is created on the destination chain when the VAA is redeemed.\nIf the response only contains an origin tx the VAA was not redeemed.",
+ "tags": [
+ "wormholescan"
+ ],
+ "operationId": "find-global-transaction-by-id",
+ "parameters": [
+ {
+ "type": "integer",
+ "description": "id of the blockchain",
+ "name": "chain_id",
+ "in": "path",
+ "required": true
+ },
+ {
+ "type": "string",
+ "description": "address of the emitter",
+ "name": "emitter",
+ "in": "path",
+ "required": true
+ },
+ {
+ "type": "integer",
+ "description": "sequence of the VAA",
+ "name": "seq",
+ "in": "path",
+ "required": true
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "OK",
+ "schema": {
+ "$ref": "#/definitions/transactions.Tx"
+ }
+ },
+ "400": {
+ "description": "Bad Request"
+ },
+ "500": {
+ "description": "Internal Server Error"
+ }
+ }
+ }
+ },
+ "/api/v1/governor/config": {
+ "get": {
+ "description": "Returns governor configuration for all guardians.",
+ "tags": [
+ "wormholescan"
+ ],
+ "operationId": "governor-config",
+ "parameters": [
+ {
+ "type": "integer",
+ "description": "Page number.",
+ "name": "page",
+ "in": "query"
+ },
+ {
+ "type": "integer",
+ "description": "Number of elements per page.",
+ "name": "pageSize",
+ "in": "query"
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "OK",
+ "schema": {
+ "$ref": "#/definitions/response.Response-governor_GovConfig"
+ }
+ },
+ "400": {
+ "description": "Bad Request"
+ },
+ "500": {
+ "description": "Internal Server Error"
+ }
+ }
+ }
+ },
+ "/api/v1/governor/config/:guardian_address": {
+ "get": {
+ "description": "Returns governor configuration for a given guardian.",
+ "tags": [
+ "wormholescan"
+ ],
+ "operationId": "governor-config-by-guardian-address",
+ "responses": {
+ "200": {
+ "description": "OK",
+ "schema": {
+ "$ref": "#/definitions/response.Response-governor_GovConfig"
+ }
+ },
+ "400": {
+ "description": "Bad Request"
+ },
+ "500": {
+ "description": "Internal Server Error"
+ }
+ }
+ }
+ },
+ "/api/v1/governor/enqueued_vaas/": {
+ "get": {
+ "description": "Returns enqueued VAAs for each blockchain.",
+ "tags": [
+ "wormholescan"
+ ],
+ "operationId": "governor-enqueued-vaas",
+ "parameters": [
+ {
+ "type": "integer",
+ "description": "Page number.",
+ "name": "page",
+ "in": "query"
+ },
+ {
+ "type": "integer",
+ "description": "Number of elements per page.",
+ "name": "pageSize",
+ "in": "query"
+ },
+ {
+ "enum": [
+ "ASC",
+ "DESC"
+ ],
+ "type": "string",
+ "description": "Sort results in ascending or descending order.",
+ "name": "sortOrder",
+ "in": "query"
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "OK",
+ "schema": {
+ "$ref": "#/definitions/response.Response-array_governor_EnqueuedVaas"
+ }
+ },
+ "400": {
+ "description": "Bad Request"
+ },
+ "500": {
+ "description": "Internal Server Error"
+ }
+ }
+ }
+ },
+ "/api/v1/governor/enqueued_vaas/:chain": {
+ "get": {
+ "description": "Returns all enqueued VAAs for a given blockchain.",
+ "tags": [
+ "wormholescan"
+ ],
+ "operationId": "guardians-enqueued-vaas-by-chain",
+ "parameters": [
+ {
+ "type": "integer",
+ "description": "Page number.",
+ "name": "page",
+ "in": "query"
+ },
+ {
+ "type": "integer",
+ "description": "Number of elements per page.",
+ "name": "pageSize",
+ "in": "query"
+ },
+ {
+ "enum": [
+ "ASC",
+ "DESC"
+ ],
+ "type": "string",
+ "description": "Sort results in ascending or descending order.",
+ "name": "sortOrder",
+ "in": "query"
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "OK",
+ "schema": {
+ "$ref": "#/definitions/response.Response-array_governor_EnqueuedVaaDetail"
+ }
+ },
+ "400": {
+ "description": "Bad Request"
+ },
+ "500": {
+ "description": "Internal Server Error"
+ }
+ }
+ }
+ },
+ "/api/v1/governor/limit": {
+ "get": {
+ "description": "Returns the governor limit for all blockchains.",
+ "tags": [
+ "wormholescan"
+ ],
+ "operationId": "governor-notional-limit",
+ "parameters": [
+ {
+ "type": "integer",
+ "description": "Page number.",
+ "name": "page",
+ "in": "query"
+ },
+ {
+ "type": "integer",
+ "description": "Number of elements per page.",
+ "name": "pageSize",
+ "in": "query"
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "OK",
+ "schema": {
+ "$ref": "#/definitions/response.Response-array_governor_GovernorLimit"
+ }
+ },
+ "400": {
+ "description": "Bad Request"
+ },
+ "500": {
+ "description": "Internal Server Error"
+ }
+ }
+ }
+ },
+ "/api/v1/governor/notional/available": {
+ "get": {
+ "description": "Returns the amount of notional value available for each blockchain.",
+ "tags": [
+ "wormholescan"
+ ],
+ "operationId": "governor-notional-available",
+ "parameters": [
+ {
+ "type": "integer",
+ "description": "Page number.",
+ "name": "page",
+ "in": "query"
+ },
+ {
+ "type": "integer",
+ "description": "Number of elements per page.",
+ "name": "pageSize",
+ "in": "query"
+ },
+ {
+ "enum": [
+ "ASC",
+ "DESC"
+ ],
+ "type": "string",
+ "description": "Sort results in ascending or descending order.",
+ "name": "sortOrder",
+ "in": "query"
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "OK",
+ "schema": {
+ "$ref": "#/definitions/response.Response-array_governor_NotionalAvailable"
+ }
+ },
+ "400": {
+ "description": "Bad Request"
+ },
+ "500": {
+ "description": "Internal Server Error"
+ }
+ }
+ }
+ },
+ "/api/v1/governor/notional/available/:chain": {
+ "get": {
+ "description": "Returns the amount of notional value available for a given blockchain.",
+ "tags": [
+ "wormholescan"
+ ],
+ "operationId": "governor-notional-available-by-chain",
+ "parameters": [
+ {
+ "type": "integer",
+ "description": "Page number.",
+ "name": "page",
+ "in": "query"
+ },
+ {
+ "type": "integer",
+ "description": "Number of elements per page.",
+ "name": "pageSize",
+ "in": "query"
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "OK",
+ "schema": {
+ "$ref": "#/definitions/response.Response-array_governor_NotionalAvailableDetail"
+ }
+ },
+ "400": {
+ "description": "Bad Request"
+ },
+ "500": {
+ "description": "Internal Server Error"
+ }
+ }
+ }
+ },
+ "/api/v1/governor/notional/limit": {
+ "get": {
+ "description": "Returns the detailed notional limit for all blockchains.",
+ "tags": [
+ "wormholescan"
+ ],
+ "operationId": "governor-notional-limit-detail",
+ "parameters": [
+ {
+ "type": "integer",
+ "description": "Page number.",
+ "name": "page",
+ "in": "query"
+ },
+ {
+ "type": "integer",
+ "description": "Number of elements per page.",
+ "name": "pageSize",
+ "in": "query"
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "OK",
+ "schema": {
+ "$ref": "#/definitions/response.Response-array_governor_NotionalLimitDetail"
+ }
+ },
+ "400": {
+ "description": "Bad Request"
+ },
+ "500": {
+ "description": "Internal Server Error"
+ }
+ }
+ }
+ },
+ "/api/v1/governor/notional/limit/:chain": {
+ "get": {
+ "description": "Returns the detailed notional limit available for a given blockchain.",
+ "tags": [
+ "wormholescan"
+ ],
+ "operationId": "governor-notional-limit-detail-by-chain",
+ "parameters": [
+ {
+ "type": "integer",
+ "description": "Page number.",
+ "name": "page",
+ "in": "query"
+ },
+ {
+ "type": "integer",
+ "description": "Number of elements per page.",
+ "name": "pageSize",
+ "in": "query"
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "OK",
+ "schema": {
+ "$ref": "#/definitions/response.Response-array_governor_NotionalLimitDetail"
+ }
+ },
+ "400": {
+ "description": "Bad Request"
+ },
+ "500": {
+ "description": "Internal Server Error"
+ }
+ }
+ }
+ },
+ "/api/v1/governor/notional/max_available/:chain": {
+ "get": {
+ "description": "Returns the maximum amount of notional value available for a given blockchain.",
+ "tags": [
+ "wormholescan"
+ ],
+ "operationId": "governor-max-notional-available-by-chain",
+ "responses": {
+ "200": {
+ "description": "OK",
+ "schema": {
+ "$ref": "#/definitions/response.Response-governor_MaxNotionalAvailableRecord"
+ }
+ },
+ "400": {
+ "description": "Bad Request"
+ },
+ "500": {
+ "description": "Internal Server Error"
+ }
+ }
+ }
+ },
+ "/api/v1/governor/status": {
+ "get": {
+ "description": "Returns the governor status for all guardians.",
+ "tags": [
+ "wormholescan"
+ ],
+ "operationId": "governor-status",
+ "parameters": [
+ {
+ "type": "integer",
+ "description": "Page number.",
+ "name": "page",
+ "in": "query"
+ },
+ {
+ "type": "integer",
+ "description": "Number of elements per page.",
+ "name": "pageSize",
+ "in": "query"
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "OK",
+ "schema": {
+ "$ref": "#/definitions/response.Response-array_governor_GovStatus"
+ }
+ },
+ "400": {
+ "description": "Bad Request"
+ },
+ "500": {
+ "description": "Internal Server Error"
+ }
+ }
+ }
+ },
+ "/api/v1/governor/status/:guardian_address": {
+ "get": {
+ "description": "Returns the governor status for a given guardian.",
+ "tags": [
+ "wormholescan"
+ ],
+ "operationId": "governor-status-by-guardian-address",
+ "parameters": [
+ {
+ "type": "integer",
+ "description": "Page number.",
+ "name": "page",
+ "in": "query"
+ },
+ {
+ "type": "integer",
+ "description": "Number of elements per page.",
+ "name": "pageSize",
+ "in": "query"
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "OK",
+ "schema": {
+ "$ref": "#/definitions/response.Response-governor_GovStatus"
+ }
+ },
+ "400": {
+ "description": "Bad Request"
+ },
+ "500": {
+ "description": "Internal Server Error"
+ }
+ }
+ }
+ },
+ "/api/v1/governor/vaas": {
+ "get": {
+ "description": "Returns all vaas in Governor.",
+ "tags": [
+ "wormholescan"
+ ],
+ "operationId": "governor-vaas",
+ "responses": {
+ "200": {
+ "description": "OK",
+ "schema": {
+ "$ref": "#/definitions/response.Response-array_governor_GovernorVaasResponse"
+ }
+ },
+ "400": {
+ "description": "Bad Request"
+ },
+ "500": {
+ "description": "Internal Server Error"
+ }
+ }
+ }
+ },
+ "/api/v1/health": {
+ "get": {
+ "description": "Health check",
+ "tags": [
+ "wormholescan"
+ ],
+ "operationId": "health-check",
+ "responses": {
+ "200": {
+ "description": "OK",
+ "schema": {
+ "type": "object",
+ "properties": {
+ "status": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad Request"
+ },
+ "500": {
+ "description": "Internal Server Error"
+ }
+ }
+ }
+ },
+ "/api/v1/last-txs": {
+ "get": {
+ "description": "Returns the number of transactions by a defined time span and sample rate.",
+ "tags": [
+ "wormholescan"
+ ],
+ "operationId": "get-last-transactions",
+ "parameters": [
+ {
+ "type": "string",
+ "description": "Time Span, default: 1d, supported values: [1d, 1w, 1mo]. 1mo ​​is 30 days.",
+ "name": "timeSpan",
+ "in": "query"
+ },
+ {
+ "type": "string",
+ "description": "Sample Rate, default: 1h, supported values: [1h, 1d]. Valid configurations with timeSpan: 1d/1h, 1w/1d, 1mo/1d",
+ "name": "sampleRate",
+ "in": "query"
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "OK",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/transactions.TransactionCountResult"
+ }
+ }
+ },
+ "400": {
+ "description": "Bad Request"
+ },
+ "500": {
+ "description": "Internal Server Error"
+ }
+ }
+ }
+ },
+ "/api/v1/native-token-transfer/activity": {
+ "get": {
+ "description": "Returns a list of values (tx count or notional) of the Native Token Transfer for a emitter and destination chains.",
+ "tags": [
+ "wormholescan"
+ ],
+ "operationId": "/api/v1/native-token-transfer/activity",
+ "parameters": [
+ {
+ "type": "string",
+ "description": "Symbol of the native-token-transfer token.",
+ "name": "symbol",
+ "in": "query",
+ "required": true
+ },
+ {
+ "type": "string",
+ "description": "Renders the results using notional or tx count (default is notional).",
+ "name": "by",
+ "in": "query"
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "OK",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/stats.NativeTokenTransferActivity"
+ }
+ }
+ },
+ "400": {
+ "description": "Bad Request"
+ },
+ "500": {
+ "description": "Internal Server Error"
+ }
+ }
+ }
+ },
+ "/api/v1/native-token-transfer/summary": {
+ "get": {
+ "description": "Returns a summary of the Native Token Transfer.",
+ "tags": [
+ "wormholescan"
+ ],
+ "operationId": "/api/v1/native-token-transfer/summary",
+ "parameters": [
+ {
+ "type": "string",
+ "description": "coingecko_id of the desired token.",
+ "name": "coingecko_id",
+ "in": "query",
+ "required": true
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "OK",
+ "schema": {
+ "$ref": "#/definitions/stats.NativeTokenTransferSummary"
+ }
+ },
+ "400": {
+ "description": "Bad Request"
+ },
+ "500": {
+ "description": "Internal Server Error"
+ }
+ }
+ }
+ },
+ "/api/v1/native-token-transfer/token-list": {
+ "get": {
+ "description": "Returns the list of supported Native Token Transfer tokens.",
+ "tags": [
+ "wormholescan"
+ ],
+ "operationId": "/api/v1/native-token-transfer/token-list",
+ "parameters": [
+ {
+ "type": "string",
+ "description": "Specify true/false if the response includes links.",
+ "name": "withLinks",
+ "in": "query",
+ "required": true
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "OK",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/stats.Token"
+ }
+ }
+ },
+ "400": {
+ "description": "Bad Request"
+ },
+ "500": {
+ "description": "Internal Server Error"
+ }
+ }
+ }
+ },
+ "/api/v1/native-token-transfer/top-address": {
+ "get": {
+ "description": "Returns a list of values (tx count or notional) of the Native Token Transfer for address.",
+ "tags": [
+ "wormholescan"
+ ],
+ "operationId": "/api/v1/native-token-transfer/top-address",
+ "parameters": [
+ {
+ "type": "string",
+ "description": "Symbol of the native-token-transfer token.",
+ "name": "symbol",
+ "in": "query",
+ "required": true
+ },
+ {
+ "type": "string",
+ "description": "Renders the results using notional or tx count (default is notional).",
+ "name": "by",
+ "in": "query"
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "OK",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/stats.NativeTokenTransferTopAddress"
+ }
+ }
+ },
+ "400": {
+ "description": "Bad Request"
+ },
+ "500": {
+ "description": "Internal Server Error"
+ }
+ }
+ }
+ },
+ "/api/v1/native-token-transfer/top-holder": {
+ "get": {
+ "description": "Returns a list of volume and chain of the Native Token Transfer for top holders.",
+ "tags": [
+ "wormholescan"
+ ],
+ "operationId": "/api/v1/native-token-transfer/top-holder",
+ "parameters": [
+ {
+ "type": "string",
+ "description": "Coingecko_id of the native-token-transfer token.",
+ "name": "coingecko_id",
+ "in": "query",
+ "required": true
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "OK",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/stats.NativeTokenTransferTopHolder"
+ }
+ }
+ },
+ "400": {
+ "description": "Bad Request"
+ },
+ "404": {
+ "description": "Not Found"
+ },
+ "500": {
+ "description": "Internal Server Error"
+ }
+ }
+ }
+ },
+ "/api/v1/native-token-transfer/transfer-by-time": {
+ "get": {
+ "description": "Returns a list of values (tx count or notional) of the Native Token Transfer for a emitter and destination chains.",
+ "tags": [
+ "wormholescan"
+ ],
+ "operationId": "/api/v1/native-token-transfer/transfer-by-time",
+ "parameters": [
+ {
+ "type": "string",
+ "description": "From date, supported format 2006-01-02T15:04:05Z07:00",
+ "name": "from",
+ "in": "query",
+ "required": true
+ },
+ {
+ "type": "string",
+ "description": "To date, supported format 2006-01-02T15:04:05Z07:00",
+ "name": "to",
+ "in": "query",
+ "required": true
+ },
+ {
+ "type": "string",
+ "description": "Symbol of the native-token-transfer token.",
+ "name": "symbol",
+ "in": "query",
+ "required": true
+ },
+ {
+ "type": "string",
+ "description": "Renders the results using notional or tx count (default is notional).",
+ "name": "by",
+ "in": "query"
+ },
+ {
+ "type": "string",
+ "description": "Time Span, supported values: [1h, 1d, 1mo, 1y].",
+ "name": "timeSpan",
+ "in": "query",
+ "required": true
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "OK",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/stats.NativeTokenTransferByTime"
+ }
+ }
+ },
+ "400": {
+ "description": "Bad Request"
+ },
+ "500": {
+ "description": "Internal Server Error"
+ }
+ }
+ }
+ },
+ "/api/v1/observations": {
+ "get": {
+ "description": "Returns all observations, sorted in descending timestamp order.",
+ "tags": [
+ "wormholescan"
+ ],
+ "operationId": "find-observations",
+ "parameters": [
+ {
+ "type": "integer",
+ "description": "Page number.",
+ "name": "page",
+ "in": "query"
+ },
+ {
+ "type": "integer",
+ "description": "Number of elements per page.",
+ "name": "pageSize",
+ "in": "query"
+ },
+ {
+ "type": "string",
+ "description": "Transaction hash of the Observations",
+ "name": "txHash",
+ "in": "query"
+ },
+ {
+ "enum": [
+ "ASC",
+ "DESC"
+ ],
+ "type": "string",
+ "description": "Sort results in ascending or descending order.",
+ "name": "sortOrder",
+ "in": "query"
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "OK",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/observations.ObservationDoc"
+ }
+ }
+ },
+ "400": {
+ "description": "Bad Request"
+ },
+ "500": {
+ "description": "Internal Server Error"
+ }
+ }
+ }
+ },
+ "/api/v1/observations/:chain": {
+ "get": {
+ "description": "Returns all observations for a given blockchain, sorted in descending timestamp order.",
+ "tags": [
+ "wormholescan"
+ ],
+ "operationId": "find-observations-by-chain",
+ "parameters": [
+ {
+ "type": "integer",
+ "description": "Page number.",
+ "name": "page",
+ "in": "query"
+ },
+ {
+ "type": "integer",
+ "description": "Number of elements per page.",
+ "name": "pageSize",
+ "in": "query"
+ },
+ {
+ "enum": [
+ "ASC",
+ "DESC"
+ ],
+ "type": "string",
+ "description": "Sort results in ascending or descending order.",
+ "name": "sortOrder",
+ "in": "query"
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "OK",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/observations.ObservationDoc"
+ }
+ }
+ },
+ "400": {
+ "description": "Bad Request"
+ },
+ "500": {
+ "description": "Internal Server Error"
+ }
+ }
+ }
+ },
+ "/api/v1/observations/:chain/:emitter": {
+ "get": {
+ "description": "Returns all observations for a specific emitter address, sorted in descending timestamp order.",
+ "tags": [
+ "wormholescan"
+ ],
+ "operationId": "find-observations-by-emitter",
+ "parameters": [
+ {
+ "type": "integer",
+ "description": "Page number.",
+ "name": "page",
+ "in": "query"
+ },
+ {
+ "type": "integer",
+ "description": "Number of elements per page.",
+ "name": "pageSize",
+ "in": "query"
+ },
+ {
+ "enum": [
+ "ASC",
+ "DESC"
+ ],
+ "type": "string",
+ "description": "Sort results in ascending or descending order.",
+ "name": "sortOrder",
+ "in": "query"
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "OK",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/observations.ObservationDoc"
+ }
+ }
+ },
+ "400": {
+ "description": "Bad Request"
+ },
+ "500": {
+ "description": "Internal Server Error"
+ }
+ }
+ }
+ },
+ "/api/v1/observations/:chain/:emitter/:sequence": {
+ "get": {
+ "description": "Find observations identified by emitter chain, emitter address and sequence.",
+ "tags": [
+ "wormholescan"
+ ],
+ "operationId": "find-observations-by-sequence",
+ "parameters": [
+ {
+ "type": "integer",
+ "description": "Page number.",
+ "name": "page",
+ "in": "query"
+ },
+ {
+ "type": "integer",
+ "description": "Number of elements per page.",
+ "name": "pageSize",
+ "in": "query"
+ },
+ {
+ "enum": [
+ "ASC",
+ "DESC"
+ ],
+ "type": "string",
+ "description": "Sort results in ascending or descending order.",
+ "name": "sortOrder",
+ "in": "query"
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "OK",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/observations.ObservationDoc"
+ }
+ }
+ },
+ "400": {
+ "description": "Bad Request"
+ },
+ "500": {
+ "description": "Internal Server Error"
+ }
+ }
+ }
+ },
+ "/api/v1/observations/:chain/:emitter/:sequence/:signer/:hash": {
+ "get": {
+ "description": "Find a specific observation.",
+ "tags": [
+ "wormholescan"
+ ],
+ "operationId": "find-observations-by-id",
+ "parameters": [
+ {
+ "type": "integer",
+ "description": "Page number.",
+ "name": "page",
+ "in": "query"
+ },
+ {
+ "type": "integer",
+ "description": "Number of elements per page.",
+ "name": "pageSize",
+ "in": "query"
+ },
+ {
+ "enum": [
+ "ASC",
+ "DESC"
+ ],
+ "type": "string",
+ "description": "Sort results in ascending or descending order.",
+ "name": "sortOrder",
+ "in": "query"
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "OK",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/observations.ObservationDoc"
+ }
+ }
+ },
+ "400": {
+ "description": "Bad Request"
+ },
+ "500": {
+ "description": "Internal Server Error"
+ }
+ }
+ }
+ },
+ "/api/v1/operations": {
+ "get": {
+ "description": "Find all operations.",
+ "tags": [
+ "wormholescan"
+ ],
+ "operationId": "get-operations",
+ "parameters": [
+ {
+ "type": "string",
+ "description": "address of the emitter",
+ "name": "address",
+ "in": "query"
+ },
+ {
+ "type": "string",
+ "description": "hash of the transaction",
+ "name": "txHash",
+ "in": "query"
+ },
+ {
+ "type": "integer",
+ "description": "page number",
+ "name": "page",
+ "in": "query"
+ },
+ {
+ "type": "integer",
+ "description": "pageSize",
+ "name": "pageSize",
+ "in": "query"
+ },
+ {
+ "type": "string",
+ "description": "source chains of the operation, separated by comma",
+ "name": "sourceChain",
+ "in": "query"
+ },
+ {
+ "type": "string",
+ "description": "target chains of the operation, separated by comma",
+ "name": "targetChain",
+ "in": "query"
+ },
+ {
+ "type": "string",
+ "description": "appID of the operation",
+ "name": "appId",
+ "in": "query"
+ },
+ {
+ "type": "boolean",
+ "description": "single appId of the operation",
+ "name": "exclusiveAppId",
+ "in": "query"
+ },
+ {
+ "type": "string",
+ "description": "beginning of period",
+ "name": "from",
+ "in": "query"
+ },
+ {
+ "type": "string",
+ "description": "end of period",
+ "name": "to",
+ "in": "query"
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "OK",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/operations.OperationResponse"
+ }
+ }
+ },
+ "400": {
+ "description": "Bad Request"
+ },
+ "500": {
+ "description": "Internal Server Error"
+ }
+ }
+ }
+ },
+ "/api/v1/operations/{chain_id}/{emitter}/{seq}": {
+ "get": {
+ "description": "Find operations by ID (chainID/emitter/sequence).",
+ "tags": [
+ "wormholescan"
+ ],
+ "operationId": "get-operation-by-id",
+ "parameters": [
+ {
+ "type": "integer",
+ "description": "id of the blockchain",
+ "name": "chain_id",
+ "in": "path",
+ "required": true
+ },
+ {
+ "type": "string",
+ "description": "address of the emitter",
+ "name": "emitter",
+ "in": "path",
+ "required": true
+ },
+ {
+ "type": "integer",
+ "description": "sequence of the VAA",
+ "name": "seq",
+ "in": "path",
+ "required": true
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "OK",
+ "schema": {
+ "$ref": "#/definitions/operations.OperationResponse"
+ }
+ },
+ "400": {
+ "description": "Bad Request"
+ },
+ "500": {
+ "description": "Internal Server Error"
+ }
+ }
+ }
+ },
+ "/api/v1/protocols/stats": {
+ "get": {
+ "description": "Returns the representative stats for the top protocols",
+ "tags": [
+ "wormholescan"
+ ],
+ "operationId": "get-top-protocols-stats",
+ "responses": {
+ "200": {
+ "description": "OK",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/protocols.ProtocolTotalValuesDTO"
+ }
+ }
+ },
+ "500": {
+ "description": "Internal Server Error",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/protocols.ProtocolTotalValuesDTO"
+ }
+ }
+ }
+ }
+ }
+ },
+ "/api/v1/ready": {
+ "get": {
+ "description": "Ready check",
+ "tags": [
+ "wormholescan"
+ ],
+ "operationId": "ready-check",
+ "responses": {
+ "200": {
+ "description": "OK",
+ "schema": {
+ "type": "object",
+ "properties": {
+ "ready": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad Request"
+ },
+ "500": {
+ "description": "Internal Server Error"
+ }
+ }
+ }
+ },
+ "/api/v1/relays/:chain/:emitter/:sequence": {
+ "get": {
+ "description": "Get a specific relay information by chainID, emitter address and sequence.",
+ "tags": [
+ "wormholescan"
+ ],
+ "operationId": "find-relay-by-vaa-id",
+ "responses": {
+ "200": {
+ "description": "OK",
+ "schema": {
+ "$ref": "#/definitions/relays.RelayResponse"
+ }
+ },
+ "400": {
+ "description": "Bad Request"
+ },
+ "500": {
+ "description": "Internal Server Error"
+ }
+ }
+ }
+ },
+ "/api/v1/scorecards": {
+ "get": {
+ "description": "Returns a list of KPIs for Wormhole.\nTVL is total value locked by token bridge contracts in USD.\nVolume is the all-time total volume transferred through the token bridge in USD.\n24h volume is the volume transferred through the token bridge in the last 24 hours, in USD.\nTotal Tx count is the number of transaction bridging assets since the creation of the network (does not include Pyth or other messages).\n24h tx count is the number of transaction bridging assets in the last 24 hours (does not include Pyth or other messages).\nTotal messages is the number of VAAs emitted since the creation of the network (includes Pyth messages).",
+ "tags": [
+ "wormholescan"
+ ],
+ "operationId": "get-scorecards",
+ "responses": {
+ "200": {
+ "description": "OK",
+ "schema": {
+ "$ref": "#/definitions/transactions.ScorecardsResponse"
+ }
+ },
+ "500": {
+ "description": "Internal Server Error"
+ }
+ }
+ }
+ },
+ "/api/v1/supply": {
+ "get": {
+ "description": "Get W token supply data (circulation and total supply).",
+ "tags": [
+ "wormholescan"
+ ],
+ "operationId": "supply-info",
+ "responses": {
+ "200": {
+ "description": "OK",
+ "schema": {
+ "$ref": "#/definitions/supply.SupplyInfoResponse"
+ }
+ }
+ }
+ }
+ },
+ "/api/v1/supply/circulating": {
+ "get": {
+ "description": "Get W token circulation supply.",
+ "tags": [
+ "wormholescan"
+ ],
+ "operationId": "circulating-supply",
+ "responses": {
+ "200": {
+ "description": "OK"
+ }
+ }
+ }
+ },
+ "/api/v1/supply/total": {
+ "get": {
+ "description": "Get W token total supply.",
+ "tags": [
+ "wormholescan"
+ ],
+ "operationId": "total-supply",
+ "responses": {
+ "200": {
+ "description": "OK"
+ }
+ }
+ }
+ },
+ "/api/v1/token/:chain_id/:token_address": {
+ "get": {
+ "description": "Returns a token symbol, coingecko id and address by chain and token address.",
+ "tags": [
+ "wormholescan"
+ ],
+ "operationId": "get-token-by-chain-and-address",
+ "parameters": [
+ {
+ "type": "integer",
+ "description": "id of the blockchain",
+ "name": "chain_id",
+ "in": "path",
+ "required": true
+ },
+ {
+ "type": "string",
+ "description": "token address",
+ "name": "token_address",
+ "in": "path",
+ "required": true
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "OK",
+ "schema": {
+ "$ref": "#/definitions/transactions.Token"
+ }
+ },
+ "400": {
+ "description": "Bad Request"
+ },
+ "404": {
+ "description": "Not Found"
+ }
+ }
+ }
+ },
+ "/api/v1/top-100-corridors": {
+ "get": {
+ "description": "Returns a list of the top 100 tokens, sorted in descending order by the number of transactions.",
+ "tags": [
+ "wormholescan"
+ ],
+ "operationId": "/api/v1/top-100-corridors",
+ "parameters": [
+ {
+ "type": "string",
+ "description": "Time span, supported values: 2d and 7d (default is 2d).",
+ "name": "timeSpan",
+ "in": "query"
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "OK",
+ "schema": {
+ "$ref": "#/definitions/stats.TopCorridorsResult"
+ }
+ },
+ "400": {
+ "description": "Bad Request"
+ },
+ "500": {
+ "description": "Internal Server Error"
+ }
+ }
+ }
+ },
+ "/api/v1/top-assets-by-volume": {
+ "get": {
+ "description": "Returns a list of emitter_chain and asset pairs with ordered by volume.\nThe volume is calculated using the notional price of the symbol at the day the VAA was emitted.",
+ "tags": [
+ "wormholescan"
+ ],
+ "operationId": "get-top-assets-by-volume",
+ "parameters": [
+ {
+ "type": "string",
+ "description": "Time span, supported values: 7d, 15d, 30d.",
+ "name": "timeSpan",
+ "in": "query",
+ "required": true
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "OK",
+ "schema": {
+ "$ref": "#/definitions/transactions.TopAssetsResponse"
+ }
+ },
+ "500": {
+ "description": "Internal Server Error"
+ }
+ }
+ }
+ },
+ "/api/v1/top-chain-pairs-by-num-transfers": {
+ "get": {
+ "description": "Returns a list of the emitter_chain and destination_chain pair ordered by transfer count.",
+ "tags": [
+ "wormholescan"
+ ],
+ "operationId": "get-top-chain-pairs-by-num-transfers",
+ "parameters": [
+ {
+ "type": "string",
+ "description": "Time span, supported values: 7d, 15d, 30d.",
+ "name": "timeSpan",
+ "in": "query",
+ "required": true
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "OK",
+ "schema": {
+ "$ref": "#/definitions/transactions.TopChainPairsResponse"
+ }
+ },
+ "500": {
+ "description": "Internal Server Error"
+ }
+ }
+ }
+ },
+ "/api/v1/top-symbols-by-volume": {
+ "get": {
+ "description": "Returns a list of symbols by origin chain and tokens.\nThe volume is calculated using the notional price of the symbol at the day the VAA was emitted.",
+ "tags": [
+ "wormholescan"
+ ],
+ "operationId": "top-symbols-by-volume",
+ "parameters": [
+ {
+ "type": "string",
+ "description": "Time span, supported values: 7d, 15d and 30d (default is 7d).",
+ "name": "timeSpan",
+ "in": "query"
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "OK",
+ "schema": {
+ "$ref": "#/definitions/stats.TopSymbolByVolumeResult"
+ }
+ },
+ "400": {
+ "description": "Bad Request"
+ },
+ "500": {
+ "description": "Internal Server Error"
+ }
+ }
+ }
+ },
+ "/api/v1/transactions/": {
+ "get": {
+ "description": "Returns transactions. Output is paginated.",
+ "tags": [
+ "wormholescan"
+ ],
+ "operationId": "list-transactions",
+ "parameters": [
+ {
+ "type": "integer",
+ "description": "Page number. Starts at 0.",
+ "name": "page",
+ "in": "query"
+ },
+ {
+ "type": "integer",
+ "description": "Number of elements per page.",
+ "name": "pageSize",
+ "in": "query"
+ },
+ {
+ "enum": [
+ "ASC",
+ "DESC"
+ ],
+ "type": "string",
+ "description": "Sort results in ascending or descending order.",
+ "name": "sortOrder",
+ "in": "query"
+ },
+ {
+ "type": "string",
+ "description": "Filter transactions by Address.",
+ "name": "address",
+ "in": "query"
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "OK",
+ "schema": {
+ "$ref": "#/definitions/transactions.ListTransactionsResponse"
+ }
+ },
+ "400": {
+ "description": "Bad Request"
+ },
+ "500": {
+ "description": "Internal Server Error"
+ }
+ }
+ }
+ },
+ "/api/v1/transactions/:chain_id/:emitter/:seq": {
+ "get": {
+ "description": "Find VAA metadata by ID.",
+ "tags": [
+ "wormholescan"
+ ],
+ "operationId": "get-transaction-by-id",
+ "parameters": [
+ {
+ "type": "integer",
+ "description": "id of the blockchain",
+ "name": "chain_id",
+ "in": "path",
+ "required": true
+ },
+ {
+ "type": "string",
+ "description": "address of the emitter",
+ "name": "emitter",
+ "in": "path",
+ "required": true
+ },
+ {
+ "type": "integer",
+ "description": "sequence of the VAA",
+ "name": "seq",
+ "in": "path",
+ "required": true
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "OK",
+ "schema": {
+ "$ref": "#/definitions/transactions.TransactionDetail"
+ }
+ },
+ "400": {
+ "description": "Bad Request"
+ },
+ "500": {
+ "description": "Internal Server Error"
+ }
+ }
+ }
+ },
+ "/api/v1/vaas/": {
+ "get": {
+ "description": "Returns all VAAs. Output is paginated and can also be be sorted.",
+ "tags": [
+ "wormholescan"
+ ],
+ "operationId": "find-all-vaas",
+ "parameters": [
+ {
+ "type": "integer",
+ "description": "Page number.",
+ "name": "page",
+ "in": "query"
+ },
+ {
+ "type": "integer",
+ "description": "Number of elements per page.",
+ "name": "pageSize",
+ "in": "query"
+ },
+ {
+ "enum": [
+ "ASC",
+ "DESC"
+ ],
+ "type": "string",
+ "description": "Sort results in ascending or descending order.",
+ "name": "sortOrder",
+ "in": "query"
+ },
+ {
+ "type": "string",
+ "description": "Transaction hash of the VAA",
+ "name": "txHash",
+ "in": "query"
+ },
+ {
+ "type": "boolean",
+ "description": "include the parsed contents of the VAA, if available",
+ "name": "parsedPayload",
+ "in": "query"
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "OK",
+ "schema": {
+ "$ref": "#/definitions/response.Response-array_vaa_VaaDoc"
+ }
+ },
+ "400": {
+ "description": "Bad Request"
+ },
+ "500": {
+ "description": "Internal Server Error"
+ }
+ }
+ }
+ },
+ "/api/v1/vaas/:chain_id": {
+ "get": {
+ "description": "Returns all the VAAs generated in specific blockchain.",
+ "tags": [
+ "wormholescan"
+ ],
+ "operationId": "find-vaas-by-chain",
+ "parameters": [
+ {
+ "type": "integer",
+ "description": "id of the blockchain",
+ "name": "chain_id",
+ "in": "path",
+ "required": true
+ },
+ {
+ "type": "integer",
+ "description": "Page number.",
+ "name": "page",
+ "in": "query"
+ },
+ {
+ "type": "integer",
+ "description": "Number of elements per page.",
+ "name": "pageSize",
+ "in": "query"
+ },
+ {
+ "enum": [
+ "ASC",
+ "DESC"
+ ],
+ "type": "string",
+ "description": "Sort results in ascending or descending order.",
+ "name": "sortOrder",
+ "in": "query"
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "OK",
+ "schema": {
+ "$ref": "#/definitions/response.Response-array_vaa_VaaDoc"
+ }
+ },
+ "400": {
+ "description": "Bad Request"
+ },
+ "500": {
+ "description": "Internal Server Error"
+ }
+ }
+ }
+ },
+ "/api/v1/vaas/:chain_id/:emitter": {
+ "get": {
+ "description": "Returns all all the VAAs generated by a specific emitter address.",
+ "tags": [
+ "wormholescan"
+ ],
+ "operationId": "find-vaas-by-emitter",
+ "parameters": [
+ {
+ "type": "integer",
+ "description": "id of the blockchain",
+ "name": "chain_id",
+ "in": "path",
+ "required": true
+ },
+ {
+ "type": "string",
+ "description": "address of the emitter",
+ "name": "emitter",
+ "in": "path",
+ "required": true
+ },
+ {
+ "type": "integer",
+ "description": "destination chain (deprecated param)",
+ "name": "toChain",
+ "in": "query"
+ },
+ {
+ "type": "integer",
+ "description": "Page number.",
+ "name": "page",
+ "in": "query"
+ },
+ {
+ "type": "integer",
+ "description": "Number of elements per page.",
+ "name": "pageSize",
+ "in": "query"
+ },
+ {
+ "enum": [
+ "ASC",
+ "DESC"
+ ],
+ "type": "string",
+ "description": "Sort results in ascending or descending order.",
+ "name": "sortOrder",
+ "in": "query"
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "OK",
+ "schema": {
+ "$ref": "#/definitions/response.Response-array_vaa_VaaDoc"
+ }
+ },
+ "400": {
+ "description": "Bad Request"
+ },
+ "500": {
+ "description": "Internal Server Error"
+ }
+ }
+ }
+ },
+ "/api/v1/vaas/:chain_id/:emitter/:seq": {
+ "get": {
+ "description": "Find a VAA by ID.",
+ "tags": [
+ "wormholescan"
+ ],
+ "operationId": "find-vaa-by-id",
+ "parameters": [
+ {
+ "type": "integer",
+ "description": "id of the blockchain",
+ "name": "chain_id",
+ "in": "path",
+ "required": true
+ },
+ {
+ "type": "string",
+ "description": "address of the emitter",
+ "name": "emitter",
+ "in": "path",
+ "required": true
+ },
+ {
+ "type": "integer",
+ "description": "sequence of the VAA",
+ "name": "seq",
+ "in": "path",
+ "required": true
+ },
+ {
+ "type": "boolean",
+ "description": "include the parsed contents of the VAA, if available",
+ "name": "parsedPayload",
+ "in": "query"
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "OK",
+ "schema": {
+ "$ref": "#/definitions/response.Response-array_vaa_VaaDoc"
+ }
+ },
+ "400": {
+ "description": "Bad Request"
+ },
+ "500": {
+ "description": "Internal Server Error"
+ }
+ }
+ }
+ },
+ "/api/v1/vaas/:chain_id/:emitter/:seq/duplicated": {
+ "get": {
+ "description": "Find duplicated VAA by ID.",
+ "tags": [
+ "wormholescan"
+ ],
+ "operationId": "find-duplicated-vaa-by-id",
+ "parameters": [
+ {
+ "type": "integer",
+ "description": "id of the blockchain",
+ "name": "chain_id",
+ "in": "path",
+ "required": true
+ },
+ {
+ "type": "string",
+ "description": "address of the emitter",
+ "name": "emitter",
+ "in": "path",
+ "required": true
+ },
+ {
+ "type": "integer",
+ "description": "sequence of the VAA",
+ "name": "seq",
+ "in": "path",
+ "required": true
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "OK",
+ "schema": {
+ "$ref": "#/definitions/response.Response-array_vaa_VaaDoc"
+ }
+ },
+ "400": {
+ "description": "Bad Request"
+ },
+ "500": {
+ "description": "Internal Server Error"
+ }
+ }
+ }
+ },
+ "/api/v1/vaas/parse": {
+ "post": {
+ "description": "Parse a VAA.",
+ "tags": [
+ "wormholescan"
+ ],
+ "operationId": "parse-vaa",
+ "responses": {
+ "200": {
+ "description": "OK",
+ "schema": {
+ "$ref": "#/definitions/parser.ParseVaaWithStandarizedPropertiesdResponse"
+ }
+ },
+ "400": {
+ "description": "Bad Request"
+ },
+ "404": {
+ "description": "Not Found"
+ },
+ "500": {
+ "description": "Internal Server Error"
+ }
+ }
+ }
+ },
+ "/api/v1/vaas/vaa-counts": {
+ "get": {
+ "description": "Returns the total number of VAAs emitted for each blockchain.",
+ "tags": [
+ "wormholescan"
+ ],
+ "operationId": "get-vaa-counts",
+ "responses": {
+ "200": {
+ "description": "OK",
+ "schema": {
+ "$ref": "#/definitions/response.Response-array_vaa_VaaStats"
+ }
+ },
+ "400": {
+ "description": "Bad Request"
+ },
+ "500": {
+ "description": "Internal Server Error"
+ }
+ }
+ }
+ },
+ "/api/v1/version": {
+ "get": {
+ "description": "Get version/release information.",
+ "tags": [
+ "wormholescan"
+ ],
+ "operationId": "get-version",
+ "responses": {
+ "200": {
+ "description": "OK",
+ "schema": {
+ "$ref": "#/definitions/infrastructure.VersionResponse"
+ }
+ },
+ "400": {
+ "description": "Bad Request"
+ },
+ "500": {
+ "description": "Internal Server Error"
+ }
+ }
+ }
+ },
+ "/api/v1/x-chain-activity": {
+ "get": {
+ "description": "Returns a list of chain pairs by origin chain and destination chain.\nThe list could be rendered by notional or transaction count.\nThe volume is calculated using the notional price of the symbol at the day the VAA was emitted.",
+ "tags": [
+ "wormholescan"
+ ],
+ "operationId": "x-chain-activity",
+ "parameters": [
+ {
+ "type": "string",
+ "description": "Time span, supported values: 7d, 30d, 90d, 1y and all-time (default is 7d).",
+ "name": "timeSpan",
+ "in": "query"
+ },
+ {
+ "type": "string",
+ "description": "Renders the results using notional or tx count (default is notional).",
+ "name": "by",
+ "in": "query"
+ },
+ {
+ "type": "string",
+ "description": "List of apps separated by comma (default is all apps).",
+ "name": "apps",
+ "in": "query"
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "OK",
+ "schema": {
+ "$ref": "#/definitions/transactions.ChainActivity"
+ }
+ },
+ "400": {
+ "description": "Bad Request"
+ },
+ "500": {
+ "description": "Internal Server Error"
+ }
+ }
+ }
+ },
+ "/api/v1/x-chain-activity/tops": {
+ "get": {
+ "description": "Search for a specific period of time the number of transactions and the volume.",
+ "tags": [
+ "wormholescan"
+ ],
+ "operationId": "x-chain-activity-tops",
+ "parameters": [
+ {
+ "type": "string",
+ "description": "Time span, supported values: 1d, 1mo and 1y",
+ "name": "timespan",
+ "in": "query",
+ "required": true
+ },
+ {
+ "type": "string",
+ "description": "From date, supported format 2006-01-02T15:04:05Z07:00",
+ "name": "from",
+ "in": "query",
+ "required": true
+ },
+ {
+ "type": "string",
+ "description": "To date, supported format 2006-01-02T15:04:05Z07:00",
+ "name": "to",
+ "in": "query",
+ "required": true
+ },
+ {
+ "type": "string",
+ "description": "Search by appId",
+ "name": "appId",
+ "in": "query"
+ },
+ {
+ "type": "string",
+ "description": "Search by sourceChain",
+ "name": "sourceChain",
+ "in": "query"
+ },
+ {
+ "type": "string",
+ "description": "Search by targetChain",
+ "name": "targetChain",
+ "in": "query"
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "OK",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/transactions.ChainActivityTopResult"
+ }
+ }
+ },
+ "400": {
+ "description": "Bad Request"
+ },
+ "500": {
+ "description": "Internal Server Error"
+ }
+ }
+ }
+ },
+ "/swagger.json": {
+ "get": {
+ "description": "Returns the swagger specification for this API.",
+ "tags": [
+ "wormholescan"
+ ],
+ "operationId": "swagger",
+ "responses": {
+ "200": {
+ "description": "OK",
+ "schema": {
+ "type": "object"
+ }
+ },
+ "400": {
+ "description": "Bad Request"
+ },
+ "500": {
+ "description": "Internal Server Error"
+ }
+ }
+ }
+ },
+ "/v1/governor/available_notional_by_chain": {
+ "get": {
+ "description": "Get available notional by chainID\nSince from the wormhole-explorer point of view it is not a node, but has the information of all nodes,\nin order to build the endpoints it was assumed:\nThere are N number of remainingAvailableNotional values in the GovernorConfig collection. N = number of guardians\nfor a chainID. The smallest remainingAvailableNotional value for a chainID is used for the endpoint response.",
+ "tags": [
+ "Guardian"
+ ],
+ "operationId": "governor-available-notional-by-chain",
+ "responses": {
+ "200": {
+ "description": "OK",
+ "schema": {
+ "$ref": "#/definitions/governor.AvailableNotionalResponse"
+ }
+ },
+ "400": {
+ "description": "Bad Request"
+ },
+ "500": {
+ "description": "Internal Server Error"
+ }
+ }
+ }
+ },
+ "/v1/governor/enqueued_vaas": {
+ "get": {
+ "description": "Get enqueued VAAs",
+ "tags": [
+ "Guardian"
+ ],
+ "operationId": "guardians-enqueued-vaas",
+ "responses": {
+ "200": {
+ "description": "OK",
+ "schema": {
+ "$ref": "#/definitions/governor.EnqueuedVaaResponse"
+ }
+ },
+ "400": {
+ "description": "Bad Request"
+ },
+ "500": {
+ "description": "Internal Server Error"
+ }
+ }
+ }
+ },
+ "/v1/governor/is_vaa_enqueued/:chain_id/:emitter/:seq": {
+ "get": {
+ "description": "Check if vaa is enqueued",
+ "tags": [
+ "Guardian"
+ ],
+ "operationId": "guardians-is-vaa-enqueued",
+ "parameters": [
+ {
+ "type": "integer",
+ "description": "id of the blockchain",
+ "name": "chain_id",
+ "in": "path",
+ "required": true
+ },
+ {
+ "type": "string",
+ "description": "address of the emitter",
+ "name": "emitter",
+ "in": "path",
+ "required": true
+ },
+ {
+ "type": "integer",
+ "description": "sequence of the vaa",
+ "name": "seq",
+ "in": "path",
+ "required": true
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "OK",
+ "schema": {
+ "$ref": "#/definitions/governor.EnqueuedVaaResponse"
+ }
+ },
+ "400": {
+ "description": "Bad Request"
+ },
+ "500": {
+ "description": "Internal Server Error"
+ }
+ }
+ }
+ },
+ "/v1/governor/token_list": {
+ "get": {
+ "description": "Get token list\nSince from the wormhole-explorer point of view it is not a node, but has the information of all nodes,\nin order to build the endpoints it was assumed:\nFor tokens with the same originChainId and originAddress and different price values for each node,\nthe price that has most occurrences in all the nodes for an originChainId and originAddress is returned.",
+ "tags": [
+ "Guardian"
+ ],
+ "operationId": "guardians-token-list",
+ "responses": {
+ "200": {
+ "description": "OK",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/governor.TokenList"
+ }
+ }
+ },
+ "400": {
+ "description": "Bad Request"
+ },
+ "500": {
+ "description": "Internal Server Error"
+ }
+ }
+ }
+ },
+ "/v1/guardianset/current": {
+ "get": {
+ "description": "Get current guardian set.",
+ "tags": [
+ "Guardian"
+ ],
+ "operationId": "guardian-set",
+ "responses": {
+ "200": {
+ "description": "OK",
+ "schema": {
+ "$ref": "#/definitions/guardian.GuardianSetResponse"
+ }
+ },
+ "400": {
+ "description": "Bad Request"
+ },
+ "500": {
+ "description": "Internal Server Error"
+ }
+ }
+ }
+ },
+ "/v1/heartbeats": {
+ "get": {
+ "description": "Get heartbeats for guardians",
+ "tags": [
+ "Guardian"
+ ],
+ "operationId": "guardians-hearbeats",
+ "responses": {
+ "200": {
+ "description": "OK",
+ "schema": {
+ "$ref": "#/definitions/heartbeats.HeartbeatsResponse"
+ }
+ },
+ "400": {
+ "description": "Bad Request"
+ },
+ "500": {
+ "description": "Internal Server Error"
+ }
+ }
+ }
+ },
+ "/v1/signed_batch_vaa/:chain_id/:emitter/sequence/:seq": {
+ "get": {
+ "description": "get a batch of VAA []byte from a chainID, emitter address and sequence.",
+ "tags": [
+ "Guardian"
+ ],
+ "operationId": "guardians-find-signed-batch-vaa",
+ "parameters": [
+ {
+ "type": "integer",
+ "description": "id of the blockchain",
+ "name": "chain_id",
+ "in": "path",
+ "required": true
+ },
+ {
+ "type": "string",
+ "description": "address of the emitter",
+ "name": "emitter",
+ "in": "path",
+ "required": true
+ },
+ {
+ "type": "integer",
+ "description": "sequence of the VAA",
+ "name": "seq",
+ "in": "path",
+ "required": true
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "OK",
+ "schema": {
+ "type": "object",
+ "properties": {
+ "vaaBytes": {
+ "type": "array",
+ "items": {
+ "type": "integer"
+ }
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad Request"
+ },
+ "500": {
+ "description": "Internal Server Error"
+ }
+ }
+ }
+ },
+ "/v1/signed_vaa/:chain_id/:emitter/:seq": {
+ "get": {
+ "description": "get a VAA []byte from a chainID, emitter address and sequence.",
+ "tags": [
+ "Guardian"
+ ],
+ "operationId": "guardians-find-signed-vaa",
+ "parameters": [
+ {
+ "type": "integer",
+ "description": "id of the blockchain",
+ "name": "chain_id",
+ "in": "path",
+ "required": true
+ },
+ {
+ "type": "string",
+ "description": "address of the emitter",
+ "name": "emitter",
+ "in": "path",
+ "required": true
+ },
+ {
+ "type": "integer",
+ "description": "sequence of the VAA",
+ "name": "seq",
+ "in": "path",
+ "required": true
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "OK",
+ "schema": {
+ "type": "object",
+ "properties": {
+ "vaaBytes": {
+ "type": "array",
+ "items": {
+ "type": "integer"
+ }
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad Request"
+ },
+ "500": {
+ "description": "Internal Server Error"
+ }
+ }
+ }
+ }
+ },
+ "definitions": {
+ "address.AddressOverview": {
+ "type": "object",
+ "properties": {
+ "vaas": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/vaa.VaaDoc"
+ }
+ }
+ }
+ },
+ "github_com_wormhole-foundation_wormhole-explorer_api_routes_guardian_guardian.GuardianSet": {
+ "type": "object",
+ "properties": {
+ "addresses": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "index": {
+ "type": "integer"
+ }
+ }
+ },
+ "governor.AvailableNotionalItemResponse": {
+ "type": "object",
+ "properties": {
+ "bigTransactionSize": {
+ "type": "string"
+ },
+ "chainId": {
+ "$ref": "#/definitions/vaa.ChainID"
+ },
+ "notionalLimit": {
+ "type": "string"
+ },
+ "remainingAvailableNotional": {
+ "type": "string"
+ }
+ }
+ },
+ "governor.AvailableNotionalResponse": {
+ "type": "object",
+ "properties": {
+ "entries": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/governor.AvailableNotionalItemResponse"
+ }
+ }
+ }
+ },
+ "governor.Emitter": {
+ "type": "object",
+ "properties": {
+ "emitterAddress": {
+ "type": "string"
+ },
+ "enqueuedVaas": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/governor.EnqueuedVAA"
+ }
+ },
+ "totalEnqueuedVaas": {
+ "type": "integer"
+ }
+ }
+ },
+ "governor.EnqueuedVAA": {
+ "type": "object",
+ "properties": {
+ "notionalValue": {
+ "type": "integer"
+ },
+ "releaseTime": {
+ "type": "string"
+ },
+ "sequence": {
+ "type": "string"
+ },
+ "txHash": {
+ "type": "string"
+ }
+ }
+ },
+ "governor.EnqueuedVaa": {
+ "type": "object",
+ "properties": {
+ "chainId": {
+ "$ref": "#/definitions/vaa.ChainID"
+ },
+ "emitterAddress": {
+ "type": "string"
+ },
+ "notionalValue": {
+ "type": "integer"
+ },
+ "sequence": {
+ "type": "string"
+ },
+ "txHash": {
+ "type": "string"
+ }
+ }
+ },
+ "governor.EnqueuedVaaDetail": {
+ "type": "object",
+ "properties": {
+ "chainId": {
+ "$ref": "#/definitions/vaa.ChainID"
+ },
+ "emitterAddress": {
+ "type": "string"
+ },
+ "notionalValue": {
+ "type": "integer"
+ },
+ "releaseTime": {
+ "type": "integer"
+ },
+ "sequence": {
+ "type": "string"
+ },
+ "txHash": {
+ "type": "string"
+ }
+ }
+ },
+ "governor.EnqueuedVaaItemResponse": {
+ "type": "object",
+ "properties": {
+ "emitterAddress": {
+ "type": "string"
+ },
+ "emitterChain": {
+ "$ref": "#/definitions/vaa.ChainID"
+ },
+ "notionalValue": {
+ "type": "string"
+ },
+ "releaseTime": {
+ "type": "integer"
+ },
+ "sequence": {
+ "type": "integer"
+ },
+ "txHash": {
+ "type": "string"
+ }
+ }
+ },
+ "governor.EnqueuedVaaResponse": {
+ "type": "object",
+ "properties": {
+ "entries": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/governor.EnqueuedVaaItemResponse"
+ }
+ }
+ }
+ },
+ "governor.EnqueuedVaas": {
+ "type": "object",
+ "properties": {
+ "chainId": {
+ "$ref": "#/definitions/vaa.ChainID"
+ },
+ "enqueuedVaas": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/governor.EnqueuedVaa"
+ }
+ }
+ }
+ },
+ "governor.GovConfig": {
+ "type": "object",
+ "properties": {
+ "chains": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/governor.GovConfigChains"
+ }
+ },
+ "counter": {
+ "type": "integer"
+ },
+ "createdAt": {
+ "type": "string"
+ },
+ "id": {
+ "type": "string"
+ },
+ "nodeName": {
+ "type": "string"
+ },
+ "tokens": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/governor.GovConfigfTokens"
+ }
+ },
+ "updatedAt": {
+ "type": "string"
+ }
+ }
+ },
+ "governor.GovConfigChains": {
+ "type": "object",
+ "properties": {
+ "bigTransactionSize": {
+ "type": "integer"
+ },
+ "chainId": {
+ "$ref": "#/definitions/vaa.ChainID"
+ },
+ "notionalLimit": {
+ "type": "integer"
+ }
+ }
+ },
+ "governor.GovConfigfTokens": {
+ "type": "object",
+ "properties": {
+ "originAddress": {
+ "type": "string"
+ },
+ "originChainId": {
+ "type": "integer"
+ },
+ "price": {
+ "type": "number"
+ }
+ }
+ },
+ "governor.GovStatus": {
+ "type": "object",
+ "properties": {
+ "chains": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/governor.GovStatusChains"
+ }
+ },
+ "createdAt": {
+ "type": "string"
+ },
+ "id": {
+ "type": "string"
+ },
+ "nodeName": {
+ "type": "string"
+ },
+ "updatedAt": {
+ "type": "string"
+ }
+ }
+ },
+ "governor.GovStatusChainEmitter": {
+ "type": "object",
+ "properties": {
+ "emitterAddress": {
+ "type": "string"
+ },
+ "enqueuedVaas": {},
+ "totalEnqueuedVaas": {
+ "type": "integer"
+ }
+ }
+ },
+ "governor.GovStatusChains": {
+ "type": "object",
+ "properties": {
+ "chainId": {
+ "$ref": "#/definitions/vaa.ChainID"
+ },
+ "emitters": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/governor.GovStatusChainEmitter"
+ }
+ },
+ "remainingAvailableNotional": {
+ "type": "integer"
+ }
+ }
+ },
+ "governor.GovernorLimit": {
+ "type": "object",
+ "properties": {
+ "availableNotional": {
+ "type": "integer"
+ },
+ "chainId": {
+ "$ref": "#/definitions/vaa.ChainID"
+ },
+ "maxTransactionSize": {
+ "type": "integer"
+ },
+ "notionalLimit": {
+ "type": "integer"
+ }
+ }
+ },
+ "governor.GovernorVaasResponse": {
+ "type": "object",
+ "properties": {
+ "amount": {
+ "type": "integer"
+ },
+ "chainId": {
+ "$ref": "#/definitions/vaa.ChainID"
+ },
+ "emitterAddress": {
+ "type": "string"
+ },
+ "releaseTime": {
+ "type": "string"
+ },
+ "sequence": {
+ "type": "string"
+ },
+ "status": {
+ "type": "string"
+ },
+ "txHash": {
+ "type": "string"
+ },
+ "vaaId": {
+ "type": "string"
+ }
+ }
+ },
+ "governor.MaxNotionalAvailableRecord": {
+ "type": "object",
+ "properties": {
+ "availableNotional": {
+ "type": "integer"
+ },
+ "chainId": {
+ "$ref": "#/definitions/vaa.ChainID"
+ },
+ "createdAt": {
+ "type": "string"
+ },
+ "emitters": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/governor.Emitter"
+ }
+ },
+ "id": {
+ "type": "string"
+ },
+ "nodeName": {
+ "type": "string"
+ },
+ "updatedAt": {
+ "type": "string"
+ }
+ }
+ },
+ "governor.NotionalAvailable": {
+ "type": "object",
+ "properties": {
+ "availableNotional": {
+ "type": "integer"
+ },
+ "chainId": {
+ "$ref": "#/definitions/vaa.ChainID"
+ }
+ }
+ },
+ "governor.NotionalAvailableDetail": {
+ "type": "object",
+ "properties": {
+ "availableNotional": {
+ "type": "integer"
+ },
+ "chainId": {
+ "$ref": "#/definitions/vaa.ChainID"
+ },
+ "createdAt": {
+ "type": "string"
+ },
+ "id": {
+ "type": "string"
+ },
+ "nodeName": {
+ "type": "string"
+ },
+ "updatedAt": {
+ "type": "string"
+ }
+ }
+ },
+ "governor.NotionalLimitDetail": {
+ "type": "object",
+ "properties": {
+ "chainId": {
+ "$ref": "#/definitions/vaa.ChainID"
+ },
+ "createdAt": {
+ "type": "string"
+ },
+ "id": {
+ "type": "string"
+ },
+ "maxTransactionSize": {
+ "type": "integer"
+ },
+ "nodeName": {
+ "type": "string"
+ },
+ "notionalLimit": {
+ "type": "integer"
+ },
+ "updatedAt": {
+ "type": "string"
+ }
+ }
+ },
+ "governor.TokenList": {
+ "type": "object",
+ "properties": {
+ "originAddress": {
+ "type": "string"
+ },
+ "originChainId": {
+ "$ref": "#/definitions/vaa.ChainID"
+ },
+ "price": {
+ "type": "number"
+ }
+ }
+ },
+ "guardian.GuardianSetResponse": {
+ "type": "object",
+ "properties": {
+ "guardianSet": {
+ "$ref": "#/definitions/github_com_wormhole-foundation_wormhole-explorer_api_routes_guardian_guardian.GuardianSet"
+ }
+ }
+ },
+ "heartbeats.HeartbeatNetworkResponse": {
+ "type": "object",
+ "properties": {
+ "contractAddress": {
+ "type": "string"
+ },
+ "errorCount": {
+ "type": "string"
+ },
+ "height": {
+ "type": "string"
+ },
+ "id": {
+ "type": "integer"
+ }
+ }
+ },
+ "heartbeats.HeartbeatResponse": {
+ "type": "object",
+ "properties": {
+ "p2pNodeAddr": {
+ "type": "string"
+ },
+ "rawHeartbeat": {
+ "$ref": "#/definitions/heartbeats.RawHeartbeat"
+ },
+ "verifiedGuardianAddr": {
+ "type": "string"
+ }
+ }
+ },
+ "heartbeats.HeartbeatsResponse": {
+ "type": "object",
+ "properties": {
+ "entries": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/heartbeats.HeartbeatResponse"
+ }
+ }
+ }
+ },
+ "heartbeats.RawHeartbeat": {
+ "type": "object",
+ "properties": {
+ "bootTimestamp": {
+ "type": "string"
+ },
+ "counter": {
+ "type": "string"
+ },
+ "features": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "guardianAddr": {
+ "type": "string"
+ },
+ "networks": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/heartbeats.HeartbeatNetworkResponse"
+ }
+ },
+ "nodeName": {
+ "type": "string"
+ },
+ "timestamp": {
+ "type": "string"
+ },
+ "version": {
+ "type": "string"
+ }
+ }
+ },
+ "infrastructure.VersionResponse": {
+ "type": "object",
+ "properties": {
+ "branch": {
+ "type": "string"
+ },
+ "build": {
+ "type": "string"
+ },
+ "build_date": {
+ "type": "string"
+ },
+ "machine": {
+ "type": "string"
+ },
+ "user": {
+ "type": "string"
+ }
+ }
+ },
+ "observations.ObservationDoc": {
+ "type": "object",
+ "properties": {
+ "emitterAddr": {
+ "type": "string"
+ },
+ "emitterChain": {
+ "$ref": "#/definitions/vaa.ChainID"
+ },
+ "guardianAddr": {
+ "type": "string"
+ },
+ "hash": {
+ "type": "array",
+ "items": {
+ "type": "integer"
+ }
+ },
+ "id": {
+ "type": "string"
+ },
+ "indexedAt": {
+ "type": "string"
+ },
+ "sequence": {
+ "type": "string"
+ },
+ "signature": {
+ "type": "array",
+ "items": {
+ "type": "integer"
+ }
+ },
+ "txHash": {
+ "type": "array",
+ "items": {
+ "type": "integer"
+ }
+ },
+ "updatedAt": {
+ "type": "string"
+ }
+ }
+ },
+ "operations.Content": {
+ "type": "object",
+ "properties": {
+ "payload": {
+ "type": "object",
+ "additionalProperties": {}
+ },
+ "standarizedProperties": {
+ "$ref": "#/definitions/operations.StandardizedProperties"
+ }
+ }
+ },
+ "operations.Data": {
+ "type": "object",
+ "properties": {
+ "type": {
+ "type": "string"
+ },
+ "value": {
+ "type": "object",
+ "additionalProperties": {}
+ }
+ }
+ },
+ "operations.EmitterAddress": {
+ "type": "object",
+ "properties": {
+ "hex": {
+ "type": "string"
+ },
+ "native": {
+ "type": "string"
+ }
+ }
+ },
+ "operations.OperationResponse": {
+ "type": "object",
+ "properties": {
+ "content": {
+ "$ref": "#/definitions/operations.Content"
+ },
+ "data": {
+ "type": "object",
+ "additionalProperties": {}
+ },
+ "emitterAddress": {
+ "$ref": "#/definitions/operations.EmitterAddress"
+ },
+ "emitterChain": {
+ "$ref": "#/definitions/vaa.ChainID"
+ },
+ "id": {
+ "type": "string"
+ },
+ "sequence": {
+ "type": "string"
+ },
+ "sourceChain": {
+ "$ref": "#/definitions/operations.SourceChain"
+ },
+ "targetChain": {
+ "$ref": "#/definitions/operations.TargetChain"
+ },
+ "vaa": {
+ "$ref": "#/definitions/operations.Vaa"
+ }
+ }
+ },
+ "operations.SourceChain": {
+ "type": "object",
+ "properties": {
+ "attribute": {
+ "$ref": "#/definitions/operations.Data"
+ },
+ "chainId": {
+ "$ref": "#/definitions/vaa.ChainID"
+ },
+ "fee": {
+ "type": "string"
+ },
+ "feeUSD": {
+ "type": "string"
+ },
+ "from": {
+ "type": "string"
+ },
+ "gasTokenNotional": {
+ "type": "string"
+ },
+ "status": {
+ "type": "string"
+ },
+ "timestamp": {
+ "type": "string"
+ },
+ "transaction": {
+ "$ref": "#/definitions/operations.Transaction"
+ }
+ }
+ },
+ "operations.StandardizedProperties": {
+ "type": "object",
+ "properties": {
+ "amount": {
+ "type": "string"
+ },
+ "appIds": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "fee": {
+ "type": "string"
+ },
+ "feeAddress": {
+ "type": "string"
+ },
+ "feeChain": {
+ "$ref": "#/definitions/vaa.ChainID"
+ },
+ "fromAddress": {
+ "type": "string"
+ },
+ "fromChain": {
+ "$ref": "#/definitions/vaa.ChainID"
+ },
+ "toAddress": {
+ "type": "string"
+ },
+ "toChain": {
+ "$ref": "#/definitions/vaa.ChainID"
+ },
+ "tokenAddress": {
+ "type": "string"
+ },
+ "tokenChain": {
+ "$ref": "#/definitions/vaa.ChainID"
+ }
+ }
+ },
+ "operations.TargetChain": {
+ "type": "object",
+ "properties": {
+ "chainId": {
+ "$ref": "#/definitions/vaa.ChainID"
+ },
+ "fee": {
+ "type": "string"
+ },
+ "feeUSD": {
+ "type": "string"
+ },
+ "from": {
+ "type": "string"
+ },
+ "gasTokenNotional": {
+ "type": "string"
+ },
+ "status": {
+ "type": "string"
+ },
+ "timestamp": {
+ "type": "string"
+ },
+ "to": {
+ "type": "string"
+ },
+ "transaction": {
+ "$ref": "#/definitions/operations.Transaction"
+ }
+ }
+ },
+ "operations.Transaction": {
+ "type": "object",
+ "properties": {
+ "secondTxHash": {
+ "type": "string"
+ },
+ "txHash": {
+ "type": "string"
+ }
+ }
+ },
+ "operations.Vaa": {
+ "type": "object",
+ "properties": {
+ "guardianSetIndex": {
+ "type": "integer"
+ },
+ "isDuplicated": {
+ "type": "boolean"
+ },
+ "raw": {
+ "type": "array",
+ "items": {
+ "type": "integer"
+ }
+ }
+ }
+ },
+ "parser.ParseVaaWithStandarizedPropertiesdResponse": {
+ "type": "object",
+ "properties": {
+ "parsedPayload": {},
+ "standardizedProperties": {
+ "$ref": "#/definitions/parser.StandardizedProperties"
+ }
+ }
+ },
+ "parser.StandardizedProperties": {
+ "type": "object",
+ "properties": {
+ "amount": {
+ "type": "string"
+ },
+ "appIds": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "fee": {
+ "type": "string"
+ },
+ "feeAddress": {
+ "type": "string"
+ },
+ "feeChain": {
+ "$ref": "#/definitions/vaa.ChainID"
+ },
+ "fromAddress": {
+ "type": "string"
+ },
+ "fromChain": {
+ "$ref": "#/definitions/vaa.ChainID"
+ },
+ "normalizedDecimals": {
+ "type": "integer"
+ },
+ "toAddress": {
+ "type": "string"
+ },
+ "toChain": {
+ "$ref": "#/definitions/vaa.ChainID"
+ },
+ "tokenAddress": {
+ "type": "string"
+ },
+ "tokenChain": {
+ "$ref": "#/definitions/vaa.ChainID"
+ }
+ }
+ },
+ "protocols.ProtocolTotalValuesDTO": {
+ "type": "object",
+ "properties": {
+ "error": {
+ "type": "string"
+ },
+ "last_24_hour_volume": {
+ "type": "number"
+ },
+ "last_day_diff_percentage": {
+ "type": "string"
+ },
+ "last_day_diff_volume_percentage": {
+ "type": "string"
+ },
+ "last_day_messages": {
+ "type": "integer"
+ },
+ "protocol": {
+ "type": "string"
+ },
+ "total_messages": {
+ "type": "integer"
+ },
+ "total_value_locked": {
+ "type": "number"
+ },
+ "total_value_secured": {
+ "type": "number"
+ },
+ "total_value_transferred": {
+ "type": "number"
+ }
+ }
+ },
+ "relays.DeliveryReponse": {
+ "type": "object",
+ "properties": {
+ "budget": {
+ "type": "string"
+ },
+ "execution": {
+ "$ref": "#/definitions/relays.ResultExecutionResponse"
+ },
+ "maxRefund": {
+ "type": "string"
+ },
+ "relayGasUsed": {
+ "type": "integer"
+ },
+ "targetChainDecimals": {
+ "type": "integer"
+ }
+ }
+ },
+ "relays.InstructionsResponse": {
+ "type": "object",
+ "properties": {
+ "encodedExecutionInfo": {
+ "type": "string"
+ },
+ "extraReceiverValue": {
+ "type": "object",
+ "properties": {
+ "_hex": {
+ "type": "string"
+ },
+ "_isBigNumber": {
+ "type": "boolean"
+ }
+ }
+ },
+ "refundAddress": {
+ "type": "string"
+ },
+ "refundChainId": {
+ "type": "integer"
+ },
+ "refundDeliveryProvider": {
+ "type": "string"
+ },
+ "requestedReceiverValue": {
+ "type": "object",
+ "properties": {
+ "_hex": {
+ "type": "string"
+ },
+ "_isBigNumber": {
+ "type": "boolean"
+ }
+ }
+ },
+ "senderAddress": {
+ "type": "string"
+ },
+ "sourceDeliveryProvider": {
+ "type": "string"
+ },
+ "targetAddress": {
+ "type": "string"
+ },
+ "targetChainId": {
+ "type": "integer"
+ },
+ "vaaKeys": {
+ "type": "array",
+ "items": {}
+ }
+ }
+ },
+ "relays.RelayDataResponse": {
+ "type": "object",
+ "properties": {
+ "delivery": {
+ "$ref": "#/definitions/relays.DeliveryReponse"
+ },
+ "fromTxHash": {
+ "type": "string"
+ },
+ "instructions": {
+ "$ref": "#/definitions/relays.InstructionsResponse"
+ },
+ "maxAttempts": {
+ "type": "integer"
+ },
+ "toTxHash": {
+ "type": "string"
+ }
+ }
+ },
+ "relays.RelayResponse": {
+ "type": "object",
+ "properties": {
+ "completedAt": {
+ "type": "string"
+ },
+ "data": {
+ "$ref": "#/definitions/relays.RelayDataResponse"
+ },
+ "failedAt": {
+ "type": "string"
+ },
+ "id": {
+ "type": "string"
+ },
+ "receivedAt": {
+ "type": "string"
+ },
+ "relayer": {
+ "type": "string"
+ },
+ "status": {
+ "type": "string"
+ }
+ }
+ },
+ "relays.ResultExecutionResponse": {
+ "type": "object",
+ "properties": {
+ "detail": {
+ "type": "string"
+ },
+ "gasUsed": {
+ "type": "string"
+ },
+ "refundStatus": {
+ "type": "string"
+ },
+ "revertString": {
+ "type": "string"
+ },
+ "status": {
+ "type": "string"
+ },
+ "transactionHash": {
+ "type": "string"
+ }
+ }
+ },
+ "response.Response-address_AddressOverview": {
+ "type": "object",
+ "properties": {
+ "data": {
+ "$ref": "#/definitions/address.AddressOverview"
+ },
+ "pagination": {
+ "$ref": "#/definitions/response.ResponsePagination"
+ }
+ }
+ },
+ "response.Response-array_governor_EnqueuedVaaDetail": {
+ "type": "object",
+ "properties": {
+ "data": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/governor.EnqueuedVaaDetail"
+ }
+ },
+ "pagination": {
+ "$ref": "#/definitions/response.ResponsePagination"
+ }
+ }
+ },
+ "response.Response-array_governor_EnqueuedVaas": {
+ "type": "object",
+ "properties": {
+ "data": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/governor.EnqueuedVaas"
+ }
+ },
+ "pagination": {
+ "$ref": "#/definitions/response.ResponsePagination"
+ }
+ }
+ },
+ "response.Response-array_governor_GovStatus": {
+ "type": "object",
+ "properties": {
+ "data": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/governor.GovStatus"
+ }
+ },
+ "pagination": {
+ "$ref": "#/definitions/response.ResponsePagination"
+ }
+ }
+ },
+ "response.Response-array_governor_GovernorLimit": {
+ "type": "object",
+ "properties": {
+ "data": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/governor.GovernorLimit"
+ }
+ },
+ "pagination": {
+ "$ref": "#/definitions/response.ResponsePagination"
+ }
+ }
+ },
+ "response.Response-array_governor_GovernorVaasResponse": {
+ "type": "object",
+ "properties": {
+ "data": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/governor.GovernorVaasResponse"
+ }
+ },
+ "pagination": {
+ "$ref": "#/definitions/response.ResponsePagination"
+ }
+ }
+ },
+ "response.Response-array_governor_NotionalAvailable": {
+ "type": "object",
+ "properties": {
+ "data": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/governor.NotionalAvailable"
+ }
+ },
+ "pagination": {
+ "$ref": "#/definitions/response.ResponsePagination"
+ }
+ }
+ },
+ "response.Response-array_governor_NotionalAvailableDetail": {
+ "type": "object",
+ "properties": {
+ "data": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/governor.NotionalAvailableDetail"
+ }
+ },
+ "pagination": {
+ "$ref": "#/definitions/response.ResponsePagination"
+ }
+ }
+ },
+ "response.Response-array_governor_NotionalLimitDetail": {
+ "type": "object",
+ "properties": {
+ "data": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/governor.NotionalLimitDetail"
+ }
+ },
+ "pagination": {
+ "$ref": "#/definitions/response.ResponsePagination"
+ }
+ }
+ },
+ "response.Response-array_vaa_VaaDoc": {
+ "type": "object",
+ "properties": {
+ "data": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/vaa.VaaDoc"
+ }
+ },
+ "pagination": {
+ "$ref": "#/definitions/response.ResponsePagination"
+ }
+ }
+ },
+ "response.Response-array_vaa_VaaStats": {
+ "type": "object",
+ "properties": {
+ "data": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/vaa.VaaStats"
+ }
+ },
+ "pagination": {
+ "$ref": "#/definitions/response.ResponsePagination"
+ }
+ }
+ },
+ "response.Response-governor_GovConfig": {
+ "type": "object",
+ "properties": {
+ "data": {
+ "$ref": "#/definitions/governor.GovConfig"
+ },
+ "pagination": {
+ "$ref": "#/definitions/response.ResponsePagination"
+ }
+ }
+ },
+ "response.Response-governor_GovStatus": {
+ "type": "object",
+ "properties": {
+ "data": {
+ "$ref": "#/definitions/governor.GovStatus"
+ },
+ "pagination": {
+ "$ref": "#/definitions/response.ResponsePagination"
+ }
+ }
+ },
+ "response.Response-governor_MaxNotionalAvailableRecord": {
+ "type": "object",
+ "properties": {
+ "data": {
+ "$ref": "#/definitions/governor.MaxNotionalAvailableRecord"
+ },
+ "pagination": {
+ "$ref": "#/definitions/response.ResponsePagination"
+ }
+ }
+ },
+ "response.ResponsePagination": {
+ "type": "object",
+ "properties": {
+ "next": {
+ "type": "string"
+ }
+ }
+ },
+ "stats.NativeTokenTransferActivity": {
+ "type": "object",
+ "properties": {
+ "destinationChain": {
+ "$ref": "#/definitions/vaa.ChainID"
+ },
+ "emitterChain": {
+ "$ref": "#/definitions/vaa.ChainID"
+ },
+ "symbol": {
+ "type": "string"
+ },
+ "value": {
+ "type": "number"
+ }
+ }
+ },
+ "stats.NativeTokenTransferByTime": {
+ "type": "object",
+ "properties": {
+ "symbol": {
+ "type": "string"
+ },
+ "time": {
+ "type": "string"
+ },
+ "value": {
+ "type": "number"
+ }
+ }
+ },
+ "stats.NativeTokenTransferSummary": {
+ "type": "object",
+ "properties": {
+ "circulatingSupply": {
+ "type": "number"
+ },
+ "fullyDilutedValuation": {
+ "type": "number"
+ },
+ "image": {
+ "$ref": "#/definitions/stats.image"
+ },
+ "links": {
+ "type": "object",
+ "additionalProperties": {}
+ },
+ "marketCap": {
+ "type": "number"
+ },
+ "platforms": {
+ "type": "object",
+ "additionalProperties": {
+ "type": "string"
+ }
+ },
+ "price": {
+ "type": "number"
+ },
+ "symbol": {
+ "type": "string"
+ },
+ "totalSupply": {
+ "type": "number"
+ },
+ "totalTokenTransferred": {
+ "type": "number"
+ },
+ "totalValueTokenTransferred": {
+ "type": "number"
+ }
+ }
+ },
+ "stats.NativeTokenTransferTopAddress": {
+ "type": "object",
+ "properties": {
+ "fromAddress": {
+ "type": "string"
+ },
+ "value": {
+ "type": "number"
+ }
+ }
+ },
+ "stats.NativeTokenTransferTopHolder": {
+ "type": "object",
+ "properties": {
+ "address": {
+ "type": "string"
+ },
+ "chain": {
+ "$ref": "#/definitions/vaa.ChainID"
+ },
+ "volume": {
+ "type": "number"
+ }
+ }
+ },
+ "stats.Token": {
+ "type": "object",
+ "properties": {
+ "address": {
+ "type": "string"
+ },
+ "chain_id": {
+ "$ref": "#/definitions/vaa.ChainID"
+ },
+ "circulating_supply": {
+ "type": "number"
+ },
+ "coingecko_id": {
+ "type": "string"
+ },
+ "fully_diluted_valuation": {
+ "type": "number"
+ },
+ "image": {
+ "type": "object",
+ "properties": {
+ "large": {
+ "type": "string"
+ },
+ "small": {
+ "type": "string"
+ },
+ "thumb": {
+ "type": "string"
+ }
+ }
+ },
+ "links": {
+ "type": "object",
+ "additionalProperties": {}
+ },
+ "market_cap": {
+ "type": "number"
+ },
+ "platforms": {
+ "type": "object",
+ "additionalProperties": {
+ "type": "string"
+ }
+ },
+ "price": {
+ "type": "number"
+ },
+ "price_change_percentage_24h": {
+ "type": "number"
+ },
+ "symbol": {
+ "type": "string"
+ },
+ "total_value_locked": {
+ "type": "number"
+ },
+ "volume_24h": {
+ "type": "number"
+ }
+ }
+ },
+ "stats.TokenResult": {
+ "type": "object",
+ "properties": {
+ "emitter_chain": {
+ "$ref": "#/definitions/vaa.ChainID"
+ },
+ "token_address": {
+ "type": "string"
+ },
+ "token_chain": {
+ "$ref": "#/definitions/vaa.ChainID"
+ },
+ "txs": {
+ "type": "number"
+ },
+ "volume": {
+ "type": "number"
+ }
+ }
+ },
+ "stats.TopCorridor": {
+ "type": "object",
+ "properties": {
+ "emitter_chain": {
+ "$ref": "#/definitions/vaa.ChainID"
+ },
+ "target_chain": {
+ "$ref": "#/definitions/vaa.ChainID"
+ },
+ "token_address": {
+ "type": "string"
+ },
+ "token_chain": {
+ "$ref": "#/definitions/vaa.ChainID"
+ },
+ "txs": {
+ "type": "integer"
+ }
+ }
+ },
+ "stats.TopCorridorsResult": {
+ "type": "object",
+ "properties": {
+ "corridors": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/stats.TopCorridor"
+ }
+ }
+ }
+ },
+ "stats.TopSymbolByVolumeResult": {
+ "type": "object",
+ "properties": {
+ "symbols": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/stats.TopSymbolResult"
+ }
+ }
+ }
+ },
+ "stats.TopSymbolResult": {
+ "type": "object",
+ "properties": {
+ "symbol": {
+ "type": "string"
+ },
+ "tokens": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/stats.TokenResult"
+ }
+ },
+ "txs": {
+ "type": "number"
+ },
+ "volume": {
+ "type": "number"
+ }
+ }
+ },
+ "stats.image": {
+ "type": "object",
+ "properties": {
+ "large": {
+ "type": "string"
+ },
+ "small": {
+ "type": "string"
+ },
+ "thumb": {
+ "type": "string"
+ }
+ }
+ },
+ "supply.SupplyInfoResponse": {
+ "type": "object",
+ "properties": {
+ "circulating_supply": {
+ "type": "string"
+ },
+ "total_supply": {
+ "type": "string"
+ }
+ }
+ },
+ "transactions.AssetWithVolume": {
+ "type": "object",
+ "properties": {
+ "emitterChain": {
+ "$ref": "#/definitions/vaa.ChainID"
+ },
+ "symbol": {
+ "type": "string"
+ },
+ "tokenAddress": {
+ "type": "string"
+ },
+ "tokenChain": {
+ "$ref": "#/definitions/vaa.ChainID"
+ },
+ "volume": {
+ "type": "string"
+ }
+ }
+ },
+ "transactions.AttributeDoc": {
+ "type": "object",
+ "properties": {
+ "type": {
+ "type": "string"
+ },
+ "value": {
+ "type": "object",
+ "additionalProperties": {}
+ }
+ }
+ },
+ "transactions.ChainActivity": {
+ "type": "object",
+ "properties": {
+ "txs": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/transactions.Tx"
+ }
+ }
+ }
+ },
+ "transactions.ChainActivityTopResult": {
+ "type": "object",
+ "properties": {
+ "count": {
+ "type": "integer"
+ },
+ "destination_chain": {
+ "type": "string"
+ },
+ "emitter_chain": {
+ "type": "string"
+ },
+ "from": {
+ "type": "string"
+ },
+ "to": {
+ "type": "string"
+ },
+ "volume": {
+ "type": "integer"
+ }
+ }
+ },
+ "transactions.ChainPair": {
+ "type": "object",
+ "properties": {
+ "destinationChain": {
+ "$ref": "#/definitions/vaa.ChainID"
+ },
+ "emitterChain": {
+ "$ref": "#/definitions/vaa.ChainID"
+ },
+ "numberOfTransfers": {
+ "type": "string"
+ }
+ }
+ },
+ "transactions.Destination": {
+ "type": "object",
+ "properties": {
+ "chain": {
+ "type": "integer"
+ },
+ "percentage": {
+ "type": "number"
+ },
+ "volume": {
+ "type": "number"
+ }
+ }
+ },
+ "transactions.DestinationTx": {
+ "type": "object",
+ "properties": {
+ "blockNumber": {
+ "type": "string"
+ },
+ "chainId": {
+ "$ref": "#/definitions/vaa.ChainID"
+ },
+ "from": {
+ "type": "string"
+ },
+ "method": {
+ "type": "string"
+ },
+ "status": {
+ "type": "string"
+ },
+ "timestamp": {
+ "type": "string"
+ },
+ "to": {
+ "type": "string"
+ },
+ "txHash": {
+ "type": "string"
+ },
+ "updatedAt": {
+ "type": "string"
+ }
+ }
+ },
+ "transactions.GlobalTransactionDoc": {
+ "type": "object",
+ "properties": {
+ "destinationTx": {
+ "$ref": "#/definitions/transactions.DestinationTx"
+ },
+ "id": {
+ "type": "string"
+ },
+ "originTx": {
+ "$ref": "#/definitions/transactions.OriginTx"
+ }
+ }
+ },
+ "transactions.ListTransactionsResponse": {
+ "type": "object",
+ "properties": {
+ "transactions": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/transactions.TransactionDetail"
+ }
+ }
+ }
+ },
+ "transactions.OriginTx": {
+ "type": "object",
+ "properties": {
+ "attribute": {
+ "$ref": "#/definitions/transactions.AttributeDoc"
+ },
+ "from": {
+ "type": "string"
+ },
+ "status": {
+ "type": "string"
+ },
+ "txHash": {
+ "type": "string"
+ }
+ }
+ },
+ "transactions.ScorecardsResponse": {
+ "type": "object",
+ "properties": {
+ "24h_messages": {
+ "description": "Number of VAAs emitted in the last 24 hours (includes Pyth messages).",
+ "type": "string"
+ },
+ "24h_volume": {
+ "description": "Volume transferred through the token bridge in the last 24 hours, in USD.",
+ "type": "string"
+ },
+ "30d_volume": {
+ "description": "Volume transferred through the token bridge in the last 24 hours, in USD.",
+ "type": "string"
+ },
+ "7d_volume": {
+ "description": "Volume transferred through the token bridge in the last 24 hours, in USD.",
+ "type": "string"
+ },
+ "total_messages": {
+ "description": "Number of VAAs emitted since the creation of the network (includes Pyth messages).",
+ "type": "string"
+ },
+ "total_tx_count": {
+ "description": "Number of VAAs emitted since the creation of the network (does not include Pyth messages)",
+ "type": "string"
+ },
+ "total_volume": {
+ "type": "string"
+ },
+ "tvl": {
+ "description": "Total value locked in USD.",
+ "type": "string"
+ }
+ }
+ },
+ "transactions.Token": {
+ "type": "object",
+ "properties": {
+ "coingeckoId": {
+ "type": "string"
+ },
+ "decimals": {
+ "type": "integer"
+ },
+ "symbol": {
+ "type": "string"
+ }
+ }
+ },
+ "transactions.TopAssetsResponse": {
+ "type": "object",
+ "properties": {
+ "assets": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/transactions.AssetWithVolume"
+ }
+ }
+ }
+ },
+ "transactions.TopChainPairsResponse": {
+ "type": "object",
+ "properties": {
+ "chainPairs": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/transactions.ChainPair"
+ }
+ }
+ }
+ },
+ "transactions.TransactionCountResult": {
+ "type": "object",
+ "properties": {
+ "count": {
+ "type": "integer"
+ },
+ "time": {
+ "type": "string"
+ }
+ }
+ },
+ "transactions.TransactionDetail": {
+ "type": "object",
+ "properties": {
+ "emitterAddress": {
+ "description": "EmitterAddress contains the VAA's emitter address, encoded in hex.",
+ "type": "string"
+ },
+ "emitterChain": {
+ "$ref": "#/definitions/vaa.ChainID"
+ },
+ "emitterNativeAddress": {
+ "description": "EmitterNativeAddress contains the VAA's emitter address, encoded in the emitter chain's native format.",
+ "type": "string"
+ },
+ "globalTx": {
+ "$ref": "#/definitions/transactions.GlobalTransactionDoc"
+ },
+ "id": {
+ "type": "string"
+ },
+ "payload": {
+ "type": "object",
+ "additionalProperties": true
+ },
+ "standardizedProperties": {
+ "type": "object",
+ "additionalProperties": true
+ },
+ "symbol": {
+ "type": "string"
+ },
+ "timestamp": {
+ "type": "string"
+ },
+ "tokenAmount": {
+ "type": "string"
+ },
+ "txHash": {
+ "type": "string"
+ },
+ "usdAmount": {
+ "type": "string"
+ }
+ }
+ },
+ "transactions.Tx": {
+ "type": "object",
+ "properties": {
+ "chain": {
+ "type": "integer"
+ },
+ "destinations": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/transactions.Destination"
+ }
+ },
+ "percentage": {
+ "type": "number"
+ },
+ "volume": {
+ "type": "number"
+ }
+ }
+ },
+ "vaa.ChainID": {
+ "type": "integer",
+ "enum": [
+ 0,
+ 1,
+ 2,
+ 3,
+ 4,
+ 5,
+ 6,
+ 7,
+ 8,
+ 9,
+ 10,
+ 11,
+ 12,
+ 13,
+ 14,
+ 15,
+ 16,
+ 18,
+ 19,
+ 20,
+ 21,
+ 22,
+ 23,
+ 24,
+ 25,
+ 26,
+ 28,
+ 29,
+ 30,
+ 32,
+ 33,
+ 34,
+ 35,
+ 36,
+ 37,
+ 38,
+ 39,
+ 40,
+ 43,
+ 44,
+ 3104,
+ 4000,
+ 4001,
+ 4002,
+ 4003,
+ 4004,
+ 4005,
+ 4006,
+ 4007,
+ 4008,
+ 10002,
+ 10003,
+ 10004,
+ 10005,
+ 10006,
+ 10007
+ ],
+ "x-enum-varnames": [
+ "ChainIDUnset",
+ "ChainIDSolana",
+ "ChainIDEthereum",
+ "ChainIDTerra",
+ "ChainIDBSC",
+ "ChainIDPolygon",
+ "ChainIDAvalanche",
+ "ChainIDOasis",
+ "ChainIDAlgorand",
+ "ChainIDAurora",
+ "ChainIDFantom",
+ "ChainIDKarura",
+ "ChainIDAcala",
+ "ChainIDKlaytn",
+ "ChainIDCelo",
+ "ChainIDNear",
+ "ChainIDMoonbeam",
+ "ChainIDTerra2",
+ "ChainIDInjective",
+ "ChainIDOsmosis",
+ "ChainIDSui",
+ "ChainIDAptos",
+ "ChainIDArbitrum",
+ "ChainIDOptimism",
+ "ChainIDGnosis",
+ "ChainIDPythNet",
+ "ChainIDXpla",
+ "ChainIDBtc",
+ "ChainIDBase",
+ "ChainIDSei",
+ "ChainIDRootstock",
+ "ChainIDScroll",
+ "ChainIDMantle",
+ "ChainIDBlast",
+ "ChainIDXLayer",
+ "ChainIDLinea",
+ "ChainIDBerachain",
+ "ChainIDSeiEVM",
+ "ChainIDSnaxchain",
+ "ChainIDUnichain",
+ "ChainIDWormchain",
+ "ChainIDCosmoshub",
+ "ChainIDEvmos",
+ "ChainIDKujira",
+ "ChainIDNeutron",
+ "ChainIDCelestia",
+ "ChainIDStargaze",
+ "ChainIDSeda",
+ "ChainIDDymension",
+ "ChainIDProvenance",
+ "ChainIDSepolia",
+ "ChainIDArbitrumSepolia",
+ "ChainIDBaseSepolia",
+ "ChainIDOptimismSepolia",
+ "ChainIDHolesky",
+ "ChainIDPolygonSepolia"
+ ]
+ },
+ "vaa.VaaDoc": {
+ "type": "object",
+ "properties": {
+ "digest": {
+ "type": "string"
+ },
+ "emitterAddr": {
+ "type": "string"
+ },
+ "emitterChain": {
+ "$ref": "#/definitions/vaa.ChainID"
+ },
+ "emitterNativeAddr": {
+ "type": "string"
+ },
+ "guardianSetIndex": {
+ "type": "integer"
+ },
+ "id": {
+ "type": "string"
+ },
+ "indexedAt": {
+ "type": "string"
+ },
+ "isDuplicated": {
+ "type": "boolean"
+ },
+ "payload": {
+ "description": "Payload is an extension field - it is not present in the guardian API.",
+ "type": "object",
+ "additionalProperties": true
+ },
+ "timestamp": {
+ "type": "string"
+ },
+ "txHash": {
+ "description": "TxHash is an extension field - it is not present in the guardian API.",
+ "type": "string"
+ },
+ "updatedAt": {
+ "type": "string"
+ },
+ "vaa": {
+ "type": "array",
+ "items": {
+ "type": "integer"
+ }
+ },
+ "version": {
+ "type": "integer"
+ }
+ }
+ },
+ "vaa.VaaStats": {
+ "type": "object",
+ "properties": {
+ "chainId": {
+ "$ref": "#/definitions/vaa.ChainID"
+ },
+ "count": {
+ "type": "integer"
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/package.json b/package.json
index 6a5b5e25b0..7bd8281c12 100644
--- a/package.json
+++ b/package.json
@@ -165,6 +165,16 @@
"packages/kyc-oracle",
"packages/metatransaction-broadcaster",
"packages/package-utils",
- "packages/reputation-miner"
- ]
+ "packages/reputation-miner",
+ "helpers/wormholescanMock"
+ ],
+ "dependencies": {
+ "@certusone/wormhole-sdk": "^0.10.15",
+ "@grpc/grpc-js": "^1.10.8",
+ "@grpc/proto-loader": "^0.7.13",
+ "@nomicfoundation/hardhat-ethers": "^3.0.5",
+ "@types/node": "^20.11.0",
+ "express-ws": "^5.0.2",
+ "ws": "^8.17.0"
+ }
}
diff --git a/packages/package-utils/ExtendedNonceManager.js b/packages/package-utils/ExtendedNonceManager.js
index fb0e2c9ee5..2e8b18042b 100644
--- a/packages/package-utils/ExtendedNonceManager.js
+++ b/packages/package-utils/ExtendedNonceManager.js
@@ -1,4 +1,5 @@
const { NonceManager } = require("@ethersproject/experimental");
+const { parseTransaction } = require("ethers/lib/utils");
class ExtendedNonceManager extends NonceManager {
constructor(signer) {
@@ -9,8 +10,23 @@ class ExtendedNonceManager extends NonceManager {
Object.keys(this.signedTransactions).map(async (txHash) => {
const nodeTx = await this.signer.provider.getTransaction(txHash);
if (!nodeTx) {
- this.signer.provider.sendTransaction(this.signedTransactions[txHash]);
- return;
+ const txCount = await this.signer.getTransactionCount("pending");
+ const parsedTransaction = parseTransaction(this.signedTransactions[txHash]);
+ if (parsedTransaction.nonce < txCount) {
+ // It's not been mined, but it's been replaced by another tx.
+ // Resend, with a new nonce
+ delete this.signedTransactions[txHash];
+ this.sendTransaction({
+ from: parsedTransaction.from,
+ to: parsedTransaction.to,
+ value: parsedTransaction.value,
+ data: parsedTransaction.data,
+ });
+ } else {
+ // No reason to think it's been replaced, so rebroadcast.
+ this.signer.provider.sendTransaction(this.signedTransactions[txHash]);
+ return;
+ }
}
if (nodeTx.blockNumber) {
// It's been mined, so forget it.
@@ -22,25 +38,18 @@ class ExtendedNonceManager extends NonceManager {
}
async sendTransaction(transactionRequest) {
- // What nonce are we going to attach to this?
- // Definitely not any we've sent and are pending
- const pendingNonces = Object.keys(this.signedTransactions).map((txhash) => this.signedTransactions[txhash].nonce);
-
- // At least whatever the endpoint says, or whatever we've already sent if higher
- let nonce = await this.signer.getTransactionCount();
-
- // Note the order we did the above two lines in - if a tx is mined between these two lines,
- // and got removed by the `on block` handler above, by doing it in this order we won't be tripped up
- // And we'll skip any nonces we've already used
- while (pendingNonces.includes(nonce)) {
- nonce += 1;
+ try {
+ const populatedTransaction = await this.populateTransaction(transactionRequest);
+ const signedTransaction = await this.signTransaction(populatedTransaction);
+ const response = super.sendTransaction(transactionRequest);
+ const tx = await response;
+ this.signedTransactions[tx.hash] = signedTransaction;
+ return response;
+ } catch (e) {
+ const txCount = await this.signer.getTransactionCount("pending");
+ this.setTransactionCount(txCount);
+ return this.sendTransaction(transactionRequest);
}
- transactionRequest.nonce = nonce; // eslint-disable-line no-param-reassign
- this.nonce = nonce + 1;
- const response = super.sendTransaction(transactionRequest);
- const tx = await response;
- this.signedTransactions[tx.hash] = transactionRequest;
- return response;
}
}
diff --git a/packages/wormhole-relayer/config.example.js b/packages/wormhole-relayer/config.example.js
index e3388242d5..53f4153aec 100644
--- a/packages/wormhole-relayer/config.example.js
+++ b/packages/wormhole-relayer/config.example.js
@@ -5,10 +5,14 @@ module.exports = {
[wormhole.CHAIN_ID_ARBITRUM_SEPOLIA]: {
endpoints: ["http://localhost:8545"],
colonyBridgeAddress: "0x633899227A3BC1f79de097149E1E3C8097c07b1a",
+ payForGas: true,
+ evmChainId: 265669100,
},
[wormhole.CHAIN_ID_SEPOLIA]: {
endpoints: ["http://localhost:8546"],
colonyBridgeAddress: "0x161944B5601a7d3004E20d4Ca823F710838Ea1be",
+ payForGas: true,
+ evmChainId: 265669101,
},
},
};
diff --git a/packages/wormhole-relayer/index.ts b/packages/wormhole-relayer/index.ts
index 2285266ce3..1a840231da 100644
--- a/packages/wormhole-relayer/index.ts
+++ b/packages/wormhole-relayer/index.ts
@@ -1,5 +1,5 @@
import { Environment, StandardRelayerContext, RelayerApp, providers } from "@wormhole-foundation/relayer-engine";
-import { CHAIN_ID_ARBITRUM_SEPOLIA, CHAIN_ID_SEPOLIA } from "@certusone/wormhole-sdk";
+// import { CHAIN_ID_ARBITRUM_SEPOLIA, CHAIN_ID_SEPOLIA } from "@certusone/wormhole-sdk";
import * as path from "path";
@@ -110,19 +110,34 @@ const loader = new TruffleLoader({
}
const hash = ctx.sourceTxHash;
- console.log(`Got a VAA with sequence: ${vaa.sequence} from with txhash: ${hash}`);
+ console.log(`Got a VAA with id: ${vaa.id.emitterChain}/${vaa.id.emitterAddress}/${vaa.id.sequence} from txhash: ${hash}`);
- let destinationBridge;
+ const [
+ destinationEvmChainId,
+ // destinationAddress,
+ // payload
+ ] = new ethers.utils.AbiCoder().decode(["uint256", "address", "bytes"], `0x${vaa.payload.toString("hex")}`);
- if (vaa.emitterChain === CHAIN_ID_ARBITRUM_SEPOLIA) {
- destinationBridge = colonyBridges[CHAIN_ID_SEPOLIA];
- } else if (vaa.emitterChain === CHAIN_ID_SEPOLIA) {
- destinationBridge = colonyBridges[CHAIN_ID_ARBITRUM_SEPOLIA];
- } else {
- console.log("Unknown chain", vaa.emitterChain);
+ const destinationChainConfig = Object.values(config.chains).find((c) => c.evmChainId === destinationEvmChainId.toNumber());
+ if (!destinationChainConfig) {
+ console.log("No destination chain config found for chain id", destinationEvmChainId.toNumber());
return next();
}
+ if (!destinationChainConfig.payForGas) {
+ console.log("We do not pay for gas on destination chain. Skipping");
+ return next();
+ }
+
+ const destinationWormholeId = Object.keys(config.chains).find((wormholeChainId) => {
+ return config.chains[wormholeChainId].evmChainId === destinationEvmChainId.toNumber();
+ });
+ if (!destinationWormholeId) {
+ console.log("No wormhole chain id found for destination chain id", destinationEvmChainId.toNumber());
+ return next();
+ }
+
+ const destinationBridge = colonyBridges[destinationWormholeId];
try {
// TODO: Explicit gas limit is a nod to tests...
const tx = await destinationBridge.receiveMessage(ctx.vaaBytes, { gasLimit: 1000000 });
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 91166f8f80..47001c9582 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -15,29 +15,39 @@ patchedDependencies:
importers:
.:
+ dependencies:
+ '@certusone/wormhole-sdk':
+ specifier: ^0.10.15
+ version: 0.10.18(fastestsmallesttextencoderdecoder@1.0.22)(google-protobuf@3.21.4)
+ '@grpc/grpc-js':
+ specifier: ^1.10.8
+ version: 1.12.5
+ '@grpc/proto-loader':
+ specifier: ^0.7.13
+ version: 0.7.13
+ '@nomicfoundation/hardhat-ethers':
+ specifier: ^3.0.5
+ version: 3.0.8(ethers@5.7.2)(hardhat@2.22.18)
+ '@types/node':
+ specifier: ^20.11.0
+ version: 20.17.16
+ express-ws:
+ specifier: ^5.0.2
+ version: 5.0.2(express@4.21.2)
+ ws:
+ specifier: ^8.17.0
+ version: 8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)
optionalDependencies:
fsevents:
specifier: ^2.3.3
version: 2.3.3
devDependencies:
- '@certusone/wormhole-sdk':
- specifier: ^0.10.18
- version: 0.10.18(fastestsmallesttextencoderdecoder@1.0.22)(google-protobuf@3.21.4)(typescript@5.7.3)
'@codechecks/client':
specifier: ^0.1.12
version: 0.1.12(typescript@5.7.3)
'@colony/eslint-config-colony':
specifier: 10.0.0
version: 10.0.0(eslint-config-airbnb-base@15.0.0)(eslint-config-prettier@8.10.0)(eslint-plugin-eslint-comments@3.2.0)(eslint-plugin-import@2.31.0)(eslint-plugin-prettier@4.2.1)(eslint@8.57.1)(prettier@2.8.8)
- '@grpc/grpc-js':
- specifier: ^1.12.5
- version: 1.12.5
- '@grpc/proto-loader':
- specifier: ^0.7.13
- version: 0.7.13
- '@nomicfoundation/hardhat-ethers':
- specifier: ^3.0.8
- version: 3.0.8(ethers@5.7.2)(hardhat@2.22.18)
'@nomicfoundation/hardhat-network-helpers':
specifier: ^1.0.12
version: 1.0.12(hardhat@2.22.18)
@@ -59,9 +69,6 @@ importers:
'@truffle/contract':
specifier: ^4.6.31
version: 4.6.31
- '@types/node':
- specifier: ^20.17.16
- version: 20.17.16
'@typescript-eslint/eslint-plugin':
specifier: ^8.21.0
version: 8.21.0(@typescript-eslint/parser@8.21.0)(eslint@8.57.1)(typescript@5.7.3)
@@ -149,9 +156,6 @@ importers:
express:
specifier: ^4.21.2
version: 4.21.2
- express-ws:
- specifier: ^5.0.2
- version: 5.0.2(express@4.21.2)
find-in-files:
specifier: ^0.5.0
version: 0.5.0
@@ -227,9 +231,49 @@ importers:
web3-utils:
specifier: ^1.10.4
version: 1.10.4
- ws:
- specifier: ^8.18.0
- version: 8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)
+
+ helpers/wormholescanMock:
+ dependencies:
+ '@openapitools/openapi-generator-cli':
+ specifier: ^2.15.3
+ version: 2.16.2
+ dotenv:
+ specifier: ^8.0.0
+ version: 8.6.0
+ ethers:
+ specifier: ^5.7.2
+ version: 5.7.2
+ ethers-types:
+ specifier: ^3.17.3
+ version: 3.18.1(ethers@5.7.2)
+ express:
+ specifier: ^4.21.1
+ version: 4.21.2
+ openapi-generator:
+ specifier: ^0.1.39
+ version: 0.1.39(ajv@6.12.6)
+ swagger-typescript-codegen:
+ specifier: ^3.2.4
+ version: 3.2.4
+ devDependencies:
+ '@types/express':
+ specifier: ^5.0.0
+ version: 5.0.0
+ '@types/node':
+ specifier: ^22.10.0
+ version: 22.10.10
+ concurrently:
+ specifier: ^9.1.0
+ version: 9.1.2
+ nodemon:
+ specifier: ^3.1.7
+ version: 3.1.9
+ ts-node:
+ specifier: ^9.1.1
+ version: 9.1.1(typescript@5.7.3)
+ typescript:
+ specifier: ^5.7.2
+ version: 5.7.3
lib/safe-contracts:
devDependencies:
@@ -455,7 +499,7 @@ importers:
version: 0.10.17(fastestsmallesttextencoderdecoder@1.0.22)(google-protobuf@3.21.4)
'@wormhole-foundation/relayer-engine':
specifier: ^0.3.2
- version: 0.3.2(@bull-board/ui@5.21.0)(@improbable-eng/grpc-web@0.15.0)(@types/node@20.17.16)(fastestsmallesttextencoderdecoder@1.0.22)(google-protobuf@3.21.4)(typescript@5.7.3)
+ version: 0.3.2(@bull-board/ui@5.21.0)(@improbable-eng/grpc-web@0.15.0)(@types/node@22.10.10)(fastestsmallesttextencoderdecoder@1.0.22)(google-protobuf@3.21.4)(typescript@5.7.3)
ethers:
specifier: '5'
version: 5.7.2
@@ -514,13 +558,11 @@ packages:
engines: {node: '>=6.9.0'}
dependencies:
'@babel/highlight': 7.24.7
- picocolors: 1.0.1
- dev: true
+ picocolors: 1.1.1
/@babel/helper-validator-identifier@7.24.7:
resolution: {integrity: sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==}
engines: {node: '>=6.9.0'}
- dev: true
/@babel/highlight@7.24.7:
resolution: {integrity: sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==}
@@ -530,7 +572,6 @@ packages:
chalk: 2.4.2
js-tokens: 4.0.0
picocolors: 1.0.1
- dev: true
/@babel/polyfill@7.12.1:
resolution: {integrity: sha512-X0pi0V6gxLi6lFZpGmeNa4zxtwEmCs42isWLNjZZDE0Y8yVfgu0T2OAHlzBbdYlqbW/YXVvoBHpATEM+goCj8g==}
@@ -780,7 +821,7 @@ packages:
- utf-8-validate
dev: false
- /@certusone/wormhole-sdk@0.10.18(fastestsmallesttextencoderdecoder@1.0.22)(google-protobuf@3.21.4)(typescript@5.7.3):
+ /@certusone/wormhole-sdk@0.10.18(fastestsmallesttextencoderdecoder@1.0.22)(google-protobuf@3.21.4):
resolution: {integrity: sha512-VuN4AGB018ELkzTT/jN+yWgE6TWqXsHilxxCVWqGctzow2hKSFd8ADUhxhHigies436rS0vPvrgXi6m0J1+Ecw==}
deprecated: 'Please use the new Wormhole TypeScript SDK instead: @wormhole-foundation/sdk'
dependencies:
@@ -789,7 +830,7 @@ packages:
'@coral-xyz/borsh': 0.2.6(@solana/web3.js@1.98.0)
'@mysten/sui.js': 0.32.2
'@project-serum/anchor': 0.25.0
- '@solana/spl-token': 0.3.11(@solana/web3.js@1.98.0)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.7.3)
+ '@solana/spl-token': 0.3.11(@solana/web3.js@1.98.0)(fastestsmallesttextencoderdecoder@1.0.22)
'@solana/web3.js': 1.98.0
'@terra-money/terra.js': 3.1.9
'@xpla/xpla.js': 0.2.3
@@ -817,9 +858,7 @@ packages:
- react
- react-dom
- subscriptions-transport-ws
- - typescript
- utf-8-validate
- dev: true
/@certusone/wormhole-spydk@0.0.1:
resolution: {integrity: sha512-iBQoY3UnmGoWHcbn0FypA6hKsANhdHKi03UN0GPoDAeMY12j8ly+7r462TfLl5f4hOJVQd3UZ2qviohEmdicmg==}
@@ -922,7 +961,6 @@ packages:
'@solana/web3.js': 1.98.0
bn.js: 5.2.1
buffer-layout: 1.2.2
- dev: true
/@cosmjs/amino@0.28.13:
resolution: {integrity: sha512-IHnH2zGwaY69qT4mVAavr/pfzx6YE+ud1NHJbvVePlbGiz68CXTi5LHR+K0lrKB5mQ7E+ZErWz2mw5U/x+V1wQ==}
@@ -977,7 +1015,7 @@ packages:
'@cosmjs/utils': 0.28.13
'@noble/hashes': 1.4.0
bn.js: 5.2.1
- elliptic: 6.5.5
+ elliptic: 6.6.1
libsodium-wrappers: 0.7.14
/@cosmjs/crypto@0.29.5:
@@ -988,7 +1026,7 @@ packages:
'@cosmjs/utils': 0.29.5
'@noble/hashes': 1.4.0
bn.js: 5.2.1
- elliptic: 6.5.5
+ elliptic: 6.6.1
libsodium-wrappers: 0.7.14
/@cosmjs/crypto@0.30.1:
@@ -1223,7 +1261,7 @@ packages:
'@cosmjs/socket': 0.28.13
'@cosmjs/stream': 0.28.13
'@cosmjs/utils': 0.28.13
- axios: 0.21.4(debug@4.3.5)
+ axios: 0.21.4
readonly-date: 1.0.0
xstream: 11.14.0
transitivePeerDependencies:
@@ -1241,7 +1279,7 @@ packages:
'@cosmjs/socket': 0.29.5
'@cosmjs/stream': 0.29.5
'@cosmjs/utils': 0.29.5
- axios: 0.21.4(debug@4.3.5)
+ axios: 0.21.4
readonly-date: 1.0.0
xstream: 11.14.0
transitivePeerDependencies:
@@ -1260,7 +1298,7 @@ packages:
'@cosmjs/socket': 0.30.1
'@cosmjs/stream': 0.30.1
'@cosmjs/utils': 0.30.1
- axios: 0.21.4(debug@4.3.5)
+ axios: 0.21.4
readonly-date: 1.0.0
xstream: 11.14.0
transitivePeerDependencies:
@@ -2065,10 +2103,13 @@ packages:
'@ethersproject/properties': 5.7.0
'@ethersproject/strings': 5.7.0
+ /@exodus/schemasafe@1.3.0:
+ resolution: {integrity: sha512-5Aap/GaRupgNx/feGBwLLTVv8OQFfv3pq2lPRzPg9R+IOBnDgghTGW7l7EuVXOvg5cc/xSAlRW8rBrjIC3Nvqw==}
+ dev: false
+
/@fastify/busboy@2.1.1:
resolution: {integrity: sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==}
engines: {node: '>=14'}
- dev: true
/@gar/promisify@1.1.3:
resolution: {integrity: sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==}
@@ -2248,7 +2289,7 @@ packages:
dependencies:
'@injectivelabs/exceptions': 1.14.40(google-protobuf@3.21.4)
'@injectivelabs/ts-types': 1.14.40
- '@injectivelabs/utils': 1.10.12(google-protobuf@3.21.4)
+ '@injectivelabs/utils': 1.14.40(google-protobuf@3.21.4)
link-module-alias: 1.2.0
shx: 0.3.4
transitivePeerDependencies:
@@ -2285,11 +2326,11 @@ packages:
'@injectivelabs/grpc-web-react-native-transport': 0.0.2(@injectivelabs/grpc-web@0.0.1)
'@injectivelabs/indexer-proto-ts': 1.10.8-rc.4
'@injectivelabs/mito-proto-ts': 1.0.9
- '@injectivelabs/networks': 1.10.12(google-protobuf@3.21.4)
+ '@injectivelabs/networks': 1.14.40(google-protobuf@3.21.4)
'@injectivelabs/test-utils': 1.14.40(google-protobuf@3.21.4)
'@injectivelabs/token-metadata': 1.14.11(google-protobuf@3.21.4)
'@injectivelabs/ts-types': 1.14.40
- '@injectivelabs/utils': 1.10.12(google-protobuf@3.21.4)
+ '@injectivelabs/utils': 1.14.40(google-protobuf@3.21.4)
'@metamask/eth-sig-util': 4.0.1
axios: 0.27.2
bech32: 2.0.0
@@ -2371,7 +2412,7 @@ packages:
dependencies:
'@injectivelabs/exceptions': 1.14.40(google-protobuf@3.21.4)
'@injectivelabs/ts-types': 1.14.40
- axios: 0.21.4(debug@4.3.5)
+ axios: 0.21.4
bignumber.js: 9.1.2
http-status-codes: 2.3.0
link-module-alias: 1.2.0
@@ -2621,6 +2662,11 @@ packages:
call-bind: 1.0.8
dev: true
+ /@lukeed/csprng@1.1.0:
+ resolution: {integrity: sha512-Z7C/xXCiGWsg0KuKsHTKJxbWhpI3Vs5GwLfOean7MGyVFGqdRgBbAjOCh6u4bbjPc/8MJ2pZmK/0DLdCbivLDA==}
+ engines: {node: '>=8'}
+ dev: false
+
/@metamask/eth-sig-util@4.0.1:
resolution: {integrity: sha512-tghyZKLHZjcdlDqCA3gNZmLeR0XvOE9U1qoQO9ohyAZT6Pya+H9vkBPcsyXytmYLNgVoin7CKCmweo/R43V+tQ==}
engines: {node: '>=12.0.0'}
@@ -2697,6 +2743,69 @@ packages:
- bufferutil
- utf-8-validate
+ /@nestjs/axios@3.1.3(@nestjs/common@10.4.15)(axios@1.7.9)(rxjs@7.8.1):
+ resolution: {integrity: sha512-RZ/63c1tMxGLqyG3iOCVt7A72oy4x1eM6QEhd4KzCYpaVWW0igq0WSREeRoEZhIxRcZfDfIIkvsOMiM7yfVGZQ==}
+ peerDependencies:
+ '@nestjs/common': ^7.0.0 || ^8.0.0 || ^9.0.0 || ^10.0.0
+ axios: ^1.3.1
+ rxjs: ^6.0.0 || ^7.0.0
+ dependencies:
+ '@nestjs/common': 10.4.15(reflect-metadata@0.1.13)(rxjs@7.8.1)
+ axios: 1.7.9
+ rxjs: 7.8.1
+ dev: false
+
+ /@nestjs/common@10.4.15(reflect-metadata@0.1.13)(rxjs@7.8.1):
+ resolution: {integrity: sha512-vaLg1ZgwhG29BuLDxPA9OAcIlgqzp9/N8iG0wGapyUNTf4IY4O6zAHgN6QalwLhFxq7nOI021vdRojR1oF3bqg==}
+ peerDependencies:
+ class-transformer: '*'
+ class-validator: '*'
+ reflect-metadata: ^0.1.12 || ^0.2.0
+ rxjs: ^7.1.0
+ peerDependenciesMeta:
+ class-transformer:
+ optional: true
+ class-validator:
+ optional: true
+ dependencies:
+ iterare: 1.2.1
+ reflect-metadata: 0.1.13
+ rxjs: 7.8.1
+ tslib: 2.8.1
+ uid: 2.0.2
+ dev: false
+
+ /@nestjs/core@10.4.15(@nestjs/common@10.4.15)(reflect-metadata@0.1.13)(rxjs@7.8.1):
+ resolution: {integrity: sha512-UBejmdiYwaH6fTsz2QFBlC1cJHM+3UDeLZN+CiP9I1fRv2KlBZsmozGLbV5eS1JAVWJB4T5N5yQ0gjN8ZvcS2w==}
+ requiresBuild: true
+ peerDependencies:
+ '@nestjs/common': ^10.0.0
+ '@nestjs/microservices': ^10.0.0
+ '@nestjs/platform-express': ^10.0.0
+ '@nestjs/websockets': ^10.0.0
+ reflect-metadata: ^0.1.12 || ^0.2.0
+ rxjs: ^7.1.0
+ peerDependenciesMeta:
+ '@nestjs/microservices':
+ optional: true
+ '@nestjs/platform-express':
+ optional: true
+ '@nestjs/websockets':
+ optional: true
+ dependencies:
+ '@nestjs/common': 10.4.15(reflect-metadata@0.1.13)(rxjs@7.8.1)
+ '@nuxtjs/opencollective': 0.3.2
+ fast-safe-stringify: 2.1.1
+ iterare: 1.2.1
+ path-to-regexp: 3.3.0
+ reflect-metadata: 0.1.13
+ rxjs: 7.8.1
+ tslib: 2.8.1
+ uid: 2.0.2
+ transitivePeerDependencies:
+ - encoding
+ dev: false
+
/@noble/curves@1.4.2:
resolution: {integrity: sha512-TavHr8qycMChk8UwMld0ZDRvatedkzWfH8IiaeGCfymOP5i0hSCozz9vHOL0nkwk7HRMlFnAiKpS2jrUmSybcw==}
dependencies:
@@ -2713,7 +2822,6 @@ packages:
/@noble/hashes@1.2.0:
resolution: {integrity: sha512-FZfhjEDbT5GRswV3C6uvLPHMiVD6lQBmpoX5+eSiPaMTXte/IKqI5dykDxzZB/WBeK/CDuQRBWarPdi3FNY2zQ==}
- dev: true
/@noble/hashes@1.4.0:
resolution: {integrity: sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==}
@@ -2729,7 +2837,6 @@ packages:
/@noble/secp256k1@1.7.1:
resolution: {integrity: sha512-hOUk6AyBFmqVrv7k5WAw/LpszxVbj9gGN4JRkIX52fdFAj1UA61KXmZDvqVEm+pOyec3+fIeZB02LYa/pWOArw==}
- dev: true
/@nodelib/fs.scandir@2.1.5:
resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==}
@@ -2765,7 +2872,6 @@ packages:
/@nomicfoundation/edr-darwin-arm64@0.7.0:
resolution: {integrity: sha512-vAH20oh4GaSB/iQFTRcoO8jLc0CLd9XuLY9I7vtcqZWAiM4U1J4Y8cu67PWmtxbvUQOqXR7S6FtAr8/AlWm14g==}
engines: {node: '>= 18'}
- dev: true
/@nomicfoundation/edr-darwin-x64@0.4.1:
resolution: {integrity: sha512-N1MfJqEX5ixaXlyyrHnaYxzwIT27Nc/jUgLI7ts4/9kRvPTvyZRYmXS1ciKhmUFr/WvFckTCix2RJbZoGGtX7g==}
@@ -2775,7 +2881,6 @@ packages:
/@nomicfoundation/edr-darwin-x64@0.7.0:
resolution: {integrity: sha512-WHDdIrPvLlgXQr2eKypBM5xOZAwdxhDAEQIvEMQL8tEEm2qYW2bliUlssBPrs8E3bdivFbe1HizImslMAfU3+g==}
engines: {node: '>= 18'}
- dev: true
/@nomicfoundation/edr-linux-arm64-gnu@0.4.1:
resolution: {integrity: sha512-bSPOfmcFjJwDgWOV5kgZHeqg2OWu1cINrHSGjig0aVHehjcoX4Sgayrj6fyAxcOV5NQKA6WcyTFll6NrCxzWRA==}
@@ -2785,7 +2890,6 @@ packages:
/@nomicfoundation/edr-linux-arm64-gnu@0.7.0:
resolution: {integrity: sha512-WXpJB54ukz1no7gxCPXVEw9pgl/9UZ/WO3l1ctyv/T7vOygjqA4SUd6kppTs6MNXAuTiisPtvJ/fmvHiMBLrsw==}
engines: {node: '>= 18'}
- dev: true
/@nomicfoundation/edr-linux-arm64-musl@0.4.1:
resolution: {integrity: sha512-F/+DgOdeBFQDrk+SX4aFffJFBgJfd75ZtE2mjcWNAh/qWiS7NfUxdQX/5OvNo/H6EY4a+3bZH6Bgzqg4mEWvMw==}
@@ -2795,7 +2899,6 @@ packages:
/@nomicfoundation/edr-linux-arm64-musl@0.7.0:
resolution: {integrity: sha512-1iZYOcEgc+zJI7JQrlAFziuy9sBz1WgnIx3HIIu0J7lBRZ/AXeHHgATb+4InqxtEx9O3W8A0s7f11SyFqJL4Aw==}
engines: {node: '>= 18'}
- dev: true
/@nomicfoundation/edr-linux-x64-gnu@0.4.1:
resolution: {integrity: sha512-POHhTWczIXCPhzKtY0Vt/l+VCqqCx5gNR5ErwSrNnLz/arfQobZFAU+nc61BX3Jch82TW8b3AbfGI73Kh7gO0w==}
@@ -2805,7 +2908,6 @@ packages:
/@nomicfoundation/edr-linux-x64-gnu@0.7.0:
resolution: {integrity: sha512-wSjC94WcR5MM8sg9w3OsAmT6+bbmChJw6uJKoXR3qscps/jdhjzJWzfgT0XGRq3XMUfimyafW2RWOyfX3ouhrQ==}
engines: {node: '>= 18'}
- dev: true
/@nomicfoundation/edr-linux-x64-musl@0.4.1:
resolution: {integrity: sha512-uu8oNp4Ozg3H1x1We0FF+rwXfFiAvsOm5GQ+OBx9YYOXnfDPWqguQfGIkhrti9GD0iYhfQ/WOG5wvp0IzzgGSg==}
@@ -2815,7 +2917,6 @@ packages:
/@nomicfoundation/edr-linux-x64-musl@0.7.0:
resolution: {integrity: sha512-Us22+AZ7wkG1mZwxqE4S4ZcuwkEA5VrUiBOJSvKHGOgy6vFvB/Euh5Lkp4GovwjrtiXuvyGO2UmtkzymZKDxZw==}
engines: {node: '>= 18'}
- dev: true
/@nomicfoundation/edr-win32-x64-msvc@0.4.1:
resolution: {integrity: sha512-PaZHFw455z89ZiKYNTnKu+/TiVZVRI+mRJsbRTe2N0VlYfUBS1o2gdXBM12oP1t198HR7xQwEPPAslTFxGBqHA==}
@@ -2825,7 +2926,6 @@ packages:
/@nomicfoundation/edr-win32-x64-msvc@0.7.0:
resolution: {integrity: sha512-HAry0heTsWkzReVtjHwoIq3BgFCvXpVhJ5qPmTnegZGsr/KxqvMmHyDMifzKao4bycU8yrpTSyOiAJt27RWjzQ==}
engines: {node: '>= 18'}
- dev: true
/@nomicfoundation/edr@0.4.1:
resolution: {integrity: sha512-NgrMo2rI9r28uidumvd+K2/AJLdxtXsUlJr3hj/pM6S1FCd/HiWaLeLa/cjCVPcE2u1rYAa3W6UFxLCB7S5Dhw==}
@@ -2851,7 +2951,6 @@ packages:
'@nomicfoundation/edr-linux-x64-gnu': 0.7.0
'@nomicfoundation/edr-linux-x64-musl': 0.7.0
'@nomicfoundation/edr-win32-x64-msvc': 0.7.0
- dev: true
/@nomicfoundation/ethereumjs-common@4.0.4:
resolution: {integrity: sha512-9Rgb658lcWsjiicr5GzNCjI1llow/7r0k50dLL95OJ+6iZJcVbi15r3Y0xh2cIO+zgX0WIHcbzIu6FeQf9KPrg==}
@@ -2859,13 +2958,11 @@ packages:
'@nomicfoundation/ethereumjs-util': 9.0.4
transitivePeerDependencies:
- c-kzg
- dev: true
/@nomicfoundation/ethereumjs-rlp@5.0.4:
resolution: {integrity: sha512-8H1S3s8F6QueOc/X92SdrA4RDenpiAEqMg5vJH99kcQaCy/a3Q6fgseo75mgWlbanGJXSlAPtnCeG9jvfTYXlw==}
engines: {node: '>=18'}
hasBin: true
- dev: true
/@nomicfoundation/ethereumjs-tx@5.0.4:
resolution: {integrity: sha512-Xjv8wAKJGMrP1f0n2PeyfFCCojHd7iS3s/Ab7qzF1S64kxZ8Z22LCMynArYsVqiFx6rzYy548HNVEyI+AYN/kw==}
@@ -2880,7 +2977,6 @@ packages:
'@nomicfoundation/ethereumjs-rlp': 5.0.4
'@nomicfoundation/ethereumjs-util': 9.0.4
ethereum-cryptography: 0.1.3
- dev: true
/@nomicfoundation/ethereumjs-util@9.0.4:
resolution: {integrity: sha512-sLOzjnSrlx9Bb9EFNtHzK/FJFsfg2re6bsGqinFinH1gCqVfz9YYlXiMWwDM4C/L4ywuHFCYwfKTVr/QHQcU0Q==}
@@ -2893,7 +2989,6 @@ packages:
dependencies:
'@nomicfoundation/ethereumjs-rlp': 5.0.4
ethereum-cryptography: 0.1.3
- dev: true
/@nomicfoundation/hardhat-ethers@3.0.8(ethers@5.7.2)(hardhat@2.22.18):
resolution: {integrity: sha512-zhOZ4hdRORls31DTOqg+GmEZM0ujly8GGIuRY7t7szEk2zW/arY1qDug/py8AEktT00v5K+b6RvbVog+va51IA==}
@@ -2907,7 +3002,7 @@ packages:
lodash.isequal: 4.5.0
transitivePeerDependencies:
- supports-color
- dev: true
+ dev: false
/@nomicfoundation/hardhat-network-helpers@1.0.12(hardhat@2.22.18):
resolution: {integrity: sha512-xTNQNI/9xkHvjmCJnJOTyqDSl8uq1rKb2WOVmixQxFtRd7Oa3ecO8zM0cyC2YmOK+jHB9WPZ+F/ijkHg1CoORA==}
@@ -2922,49 +3017,42 @@ packages:
resolution: {integrity: sha512-JaqcWPDZENCvm++lFFGjrDd8mxtf+CtLd2MiXvMNTBD33dContTZ9TWETwNFwg7JTJT5Q9HEecH7FA+HTSsIUw==}
engines: {node: '>= 12'}
requiresBuild: true
- dev: true
optional: true
/@nomicfoundation/solidity-analyzer-darwin-x64@0.1.2:
resolution: {integrity: sha512-fZNmVztrSXC03e9RONBT+CiksSeYcxI1wlzqyr0L7hsQlK1fzV+f04g2JtQ1c/Fe74ZwdV6aQBdd6Uwl1052sw==}
engines: {node: '>= 12'}
requiresBuild: true
- dev: true
optional: true
/@nomicfoundation/solidity-analyzer-linux-arm64-gnu@0.1.2:
resolution: {integrity: sha512-3d54oc+9ZVBuB6nbp8wHylk4xh0N0Gc+bk+/uJae+rUgbOBwQSfuGIbAZt1wBXs5REkSmynEGcqx6DutoK0tPA==}
engines: {node: '>= 12'}
requiresBuild: true
- dev: true
optional: true
/@nomicfoundation/solidity-analyzer-linux-arm64-musl@0.1.2:
resolution: {integrity: sha512-iDJfR2qf55vgsg7BtJa7iPiFAsYf2d0Tv/0B+vhtnI16+wfQeTbP7teookbGvAo0eJo7aLLm0xfS/GTkvHIucA==}
engines: {node: '>= 12'}
requiresBuild: true
- dev: true
optional: true
/@nomicfoundation/solidity-analyzer-linux-x64-gnu@0.1.2:
resolution: {integrity: sha512-9dlHMAt5/2cpWyuJ9fQNOUXFB/vgSFORg1jpjX1Mh9hJ/MfZXlDdHQ+DpFCs32Zk5pxRBb07yGvSHk9/fezL+g==}
engines: {node: '>= 12'}
requiresBuild: true
- dev: true
optional: true
/@nomicfoundation/solidity-analyzer-linux-x64-musl@0.1.2:
resolution: {integrity: sha512-GzzVeeJob3lfrSlDKQw2bRJ8rBf6mEYaWY+gW0JnTDHINA0s2gPR4km5RLIj1xeZZOYz4zRw+AEeYgLRqB2NXg==}
engines: {node: '>= 12'}
requiresBuild: true
- dev: true
optional: true
/@nomicfoundation/solidity-analyzer-win32-x64-msvc@0.1.2:
resolution: {integrity: sha512-Fdjli4DCcFHb4Zgsz0uEJXZ2K7VEO+w5KVv7HmT7WO10iODdU9csC2az4jrhEsRtiR9Gfd74FlG0NYlw1BMdyA==}
engines: {node: '>= 12'}
requiresBuild: true
- dev: true
optional: true
/@nomicfoundation/solidity-analyzer@0.1.2:
@@ -2978,7 +3066,6 @@ packages:
'@nomicfoundation/solidity-analyzer-linux-x64-gnu': 0.1.2
'@nomicfoundation/solidity-analyzer-linux-x64-musl': 0.1.2
'@nomicfoundation/solidity-analyzer-win32-x64-msvc': 0.1.2
- dev: true
/@nomiclabs/hardhat-ethers@2.2.3(ethers@5.7.2)(hardhat@2.22.18):
resolution: {integrity: sha512-YhzPdzb612X591FOe68q+qXVXGG2ANZRvDo0RRUtimev85rCrAlv/TLMEZw5c+kq9AbzocLTVX/h2jVIFPL9Xg==}
@@ -3123,9 +3210,56 @@ packages:
dev: false
optional: true
+ /@nuxtjs/opencollective@0.3.2:
+ resolution: {integrity: sha512-um0xL3fO7Mf4fDxcqx9KryrB7zgRM5JSlvGN5AGkP6JLM5XEKyjeAiPbNxdXVXQ16isuAhYpvP88NgL2BGd6aA==}
+ engines: {node: '>=8.0.0', npm: '>=5.0.0'}
+ hasBin: true
+ dependencies:
+ chalk: 4.1.2
+ consola: 2.15.3
+ node-fetch: 2.7.0
+ transitivePeerDependencies:
+ - encoding
+ dev: false
+
/@one-ini/wasm@0.1.1:
resolution: {integrity: sha512-XuySG1E38YScSJoMlqovLru4KTUNSjgVTIjyh7qMX6aNN5HY5Ct5LhRJdxO79JtTzKfzV/bnWpz+zquYrISsvw==}
+ /@openapitools/openapi-generator-cli@2.16.2:
+ resolution: {integrity: sha512-AjPxFPpCr8atXYWAFRlWttWcLz0+2VEEw2dTk8wLBwzwz3+dN/8t1Zi4s89QNPJyrOm1lc+g42nNIy8MJlWOIA==}
+ engines: {node: '>=16'}
+ hasBin: true
+ requiresBuild: true
+ dependencies:
+ '@nestjs/axios': 3.1.3(@nestjs/common@10.4.15)(axios@1.7.9)(rxjs@7.8.1)
+ '@nestjs/common': 10.4.15(reflect-metadata@0.1.13)(rxjs@7.8.1)
+ '@nestjs/core': 10.4.15(@nestjs/common@10.4.15)(reflect-metadata@0.1.13)(rxjs@7.8.1)
+ '@nuxtjs/opencollective': 0.3.2
+ axios: 1.7.9
+ chalk: 4.1.2
+ commander: 8.3.0
+ compare-versions: 4.1.4
+ concurrently: 6.5.1
+ console.table: 0.10.0
+ fs-extra: 10.1.0
+ glob: 9.3.5
+ inquirer: 8.2.6
+ lodash: 4.17.21
+ proxy-agent: 6.4.0
+ reflect-metadata: 0.1.13
+ rxjs: 7.8.1
+ tslib: 2.8.1
+ transitivePeerDependencies:
+ - '@nestjs/microservices'
+ - '@nestjs/platform-express'
+ - '@nestjs/websockets'
+ - class-transformer
+ - class-validator
+ - debug
+ - encoding
+ - supports-color
+ dev: false
+
/@openzeppelin/contracts@3.4.2:
resolution: {integrity: sha512-z0zMCjyhhp4y7XKAcDAi3Vgms4T2PstwBdahiO0+9NaGICQKjynK3wduSRplTgk4LXmoO1yfDGO5RbjKYxtuxA==}
dev: true
@@ -3288,7 +3422,6 @@ packages:
'@noble/hashes': 1.2.0
'@noble/secp256k1': 1.7.1
'@scure/base': 1.1.7
- dev: true
/@scure/bip32@1.4.0:
resolution: {integrity: sha512-sVUpc0Vq3tXCkDGYVWGIZTRfnvu8LoTDaev7vbwh0omSvVORONr960MQWdKqJDCReIEmTj3PAr73O3aoxz7OPg==}
@@ -3315,7 +3448,6 @@ packages:
dependencies:
'@noble/hashes': 1.2.0
'@scure/base': 1.1.7
- dev: true
/@scure/bip39@1.3.0:
resolution: {integrity: sha512-disdg7gHuTDZtY+ZdkmLpPCk7fxZSu3gBiEGuoC1XYxv9cGx3Z6cpTggCgW6odSOOIXCiDjuGejW+aJKCY/pIQ==}
@@ -3381,7 +3513,6 @@ packages:
'@sentry/types': 5.30.0
'@sentry/utils': 5.30.0
tslib: 1.14.1
- dev: true
/@sentry/hub@5.30.0:
resolution: {integrity: sha512-2tYrGnzb1gKz2EkMDQcfLrDTvmGcQPuWxLnJKXJvYTQDGLlEvi2tWz1VIHjunmOvJrB5aIQLhm+dcMRwFZDCqQ==}
@@ -3390,7 +3521,6 @@ packages:
'@sentry/types': 5.30.0
'@sentry/utils': 5.30.0
tslib: 1.14.1
- dev: true
/@sentry/minimal@5.30.0:
resolution: {integrity: sha512-BwWb/owZKtkDX+Sc4zCSTNcvZUq7YcH3uAVlmh/gtR9rmUvbzAA3ewLuB3myi4wWRAMEtny6+J/FN/x+2wn9Xw==}
@@ -3399,7 +3529,6 @@ packages:
'@sentry/hub': 5.30.0
'@sentry/types': 5.30.0
tslib: 1.14.1
- dev: true
/@sentry/node@5.30.0:
resolution: {integrity: sha512-Br5oyVBF0fZo6ZS9bxbJZG4ApAjRqAnqFFurMVJJdunNb80brh7a5Qva2kjhm+U6r9NJAB5OmDyPkA1Qnt+QVg==}
@@ -3416,7 +3545,6 @@ packages:
tslib: 1.14.1
transitivePeerDependencies:
- supports-color
- dev: true
/@sentry/tracing@5.30.0:
resolution: {integrity: sha512-dUFowCr0AIMwiLD7Fs314Mdzcug+gBVo/+NCMyDw8tFxJkwWAKl7Qa2OZxLQ0ZHjakcj1hNKfCQJ9rhyfOl4Aw==}
@@ -3427,12 +3555,10 @@ packages:
'@sentry/types': 5.30.0
'@sentry/utils': 5.30.0
tslib: 1.14.1
- dev: true
/@sentry/types@5.30.0:
resolution: {integrity: sha512-R8xOqlSTZ+htqrfteCWU5Nk0CDN5ApUTvrlvBuiH1DyP6czDZ4ktbZB0hAgBlVcK0U+qpD3ag3Tqqpa5Q67rPw==}
engines: {node: '>=6'}
- dev: true
/@sentry/utils@5.30.0:
resolution: {integrity: sha512-zaYmoH0NWWtvnJjC9/CBseXMtKHm/tm40sz3YfJRxeQjyzRqNQPgivpd9R/oDJCYj999mzdW382p/qi2ypjLww==}
@@ -3440,12 +3566,10 @@ packages:
dependencies:
'@sentry/types': 5.30.0
tslib: 1.14.1
- dev: true
/@sindresorhus/is@0.14.0:
resolution: {integrity: sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==}
engines: {node: '>=6'}
- dev: true
/@sindresorhus/is@4.6.0:
resolution: {integrity: sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==}
@@ -3475,15 +3599,6 @@ packages:
resolution: {integrity: sha512-gLhCJXieSCrAU7acUJjbXl+IbGnqovvxQLlimztPoGgfLQ1wFYu+XJswrEVQqknZYK1pgxpxH3rZ+OKFs0ndQg==}
dependencies:
'@solana/errors': 2.0.0-preview.2
- dev: false
-
- /@solana/codecs-core@2.0.0-rc.1(typescript@5.7.3):
- resolution: {integrity: sha512-bauxqMfSs8EHD0JKESaNmNuNvkvHSuN3bbWAF5RjOfDu2PugxHrvRebmYauvSumZ3cTfQ4HJJX6PG5rN852qyQ==}
- peerDependencies:
- typescript: '>=5'
- dependencies:
- '@solana/errors': 2.0.0-rc.1(typescript@5.7.3)
- typescript: 5.7.3
/@solana/codecs-data-structures@2.0.0-preview.2:
resolution: {integrity: sha512-Xf5vIfromOZo94Q8HbR04TbgTwzigqrKII0GjYr21K7rb3nba4hUW2ir8kguY7HWFBcjHGlU5x3MevKBOLp3Zg==}
@@ -3491,33 +3606,12 @@ packages:
'@solana/codecs-core': 2.0.0-preview.2
'@solana/codecs-numbers': 2.0.0-preview.2
'@solana/errors': 2.0.0-preview.2
- dev: false
-
- /@solana/codecs-data-structures@2.0.0-rc.1(typescript@5.7.3):
- resolution: {integrity: sha512-rinCv0RrAVJ9rE/rmaibWJQxMwC5lSaORSZuwjopSUE6T0nb/MVg6Z1siNCXhh/HFTOg0l8bNvZHgBcN/yvXog==}
- peerDependencies:
- typescript: '>=5'
- dependencies:
- '@solana/codecs-core': 2.0.0-rc.1(typescript@5.7.3)
- '@solana/codecs-numbers': 2.0.0-rc.1(typescript@5.7.3)
- '@solana/errors': 2.0.0-rc.1(typescript@5.7.3)
- typescript: 5.7.3
/@solana/codecs-numbers@2.0.0-preview.2:
resolution: {integrity: sha512-aLZnDTf43z4qOnpTcDsUVy1Ci9im1Md8thWipSWbE+WM9ojZAx528oAql+Cv8M8N+6ALKwgVRhPZkto6E59ARw==}
dependencies:
'@solana/codecs-core': 2.0.0-preview.2
'@solana/errors': 2.0.0-preview.2
- dev: false
-
- /@solana/codecs-numbers@2.0.0-rc.1(typescript@5.7.3):
- resolution: {integrity: sha512-J5i5mOkvukXn8E3Z7sGIPxsThRCgSdgTWJDQeZvucQ9PT6Y3HiVXJ0pcWiOWAoQ3RX8e/f4I3IC+wE6pZiJzDQ==}
- peerDependencies:
- typescript: '>=5'
- dependencies:
- '@solana/codecs-core': 2.0.0-rc.1(typescript@5.7.3)
- '@solana/errors': 2.0.0-rc.1(typescript@5.7.3)
- typescript: 5.7.3
/@solana/codecs-strings@2.0.0-preview.2(fastestsmallesttextencoderdecoder@1.0.22):
resolution: {integrity: sha512-EgBwY+lIaHHgMJIqVOGHfIfpdmmUDNoNO/GAUGeFPf+q0dF+DtwhJPEMShhzh64X2MeCZcmSO6Kinx0Bvmmz2g==}
@@ -3528,19 +3622,6 @@ packages:
'@solana/codecs-numbers': 2.0.0-preview.2
'@solana/errors': 2.0.0-preview.2
fastestsmallesttextencoderdecoder: 1.0.22
- dev: false
-
- /@solana/codecs-strings@2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.7.3):
- resolution: {integrity: sha512-9/wPhw8TbGRTt6mHC4Zz1RqOnuPTqq1Nb4EyuvpZ39GW6O2t2Q7Q0XxiB3+BdoEjwA2XgPw6e2iRfvYgqty44g==}
- peerDependencies:
- fastestsmallesttextencoderdecoder: ^1.0.22
- typescript: '>=5'
- dependencies:
- '@solana/codecs-core': 2.0.0-rc.1(typescript@5.7.3)
- '@solana/codecs-numbers': 2.0.0-rc.1(typescript@5.7.3)
- '@solana/errors': 2.0.0-rc.1(typescript@5.7.3)
- fastestsmallesttextencoderdecoder: 1.0.22
- typescript: 5.7.3
/@solana/codecs@2.0.0-preview.2(fastestsmallesttextencoderdecoder@1.0.22):
resolution: {integrity: sha512-4HHzCD5+pOSmSB71X6w9ptweV48Zj1Vqhe732+pcAQ2cMNnN0gMPMdDq7j3YwaZDZ7yrILVV/3+HTnfT77t2yA==}
@@ -3552,21 +3633,6 @@ packages:
'@solana/options': 2.0.0-preview.2
transitivePeerDependencies:
- fastestsmallesttextencoderdecoder
- dev: false
-
- /@solana/codecs@2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.7.3):
- resolution: {integrity: sha512-qxoR7VybNJixV51L0G1RD2boZTcxmwUWnKCaJJExQ5qNKwbpSyDdWfFJfM5JhGyKe9DnPVOZB+JHWXnpbZBqrQ==}
- peerDependencies:
- typescript: '>=5'
- dependencies:
- '@solana/codecs-core': 2.0.0-rc.1(typescript@5.7.3)
- '@solana/codecs-data-structures': 2.0.0-rc.1(typescript@5.7.3)
- '@solana/codecs-numbers': 2.0.0-rc.1(typescript@5.7.3)
- '@solana/codecs-strings': 2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.7.3)
- '@solana/options': 2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.7.3)
- typescript: 5.7.3
- transitivePeerDependencies:
- - fastestsmallesttextencoderdecoder
/@solana/errors@2.0.0-preview.2:
resolution: {integrity: sha512-H2DZ1l3iYF5Rp5pPbJpmmtCauWeQXRJapkDg8epQ8BJ7cA2Ut/QEtC3CMmw/iMTcuS6uemFNLcWvlOfoQhvQuA==}
@@ -3574,38 +3640,12 @@ packages:
dependencies:
chalk: 5.3.0
commander: 12.1.0
- dev: false
-
- /@solana/errors@2.0.0-rc.1(typescript@5.7.3):
- resolution: {integrity: sha512-ejNvQ2oJ7+bcFAYWj225lyRkHnixuAeb7RQCixm+5mH4n1IA4Qya/9Bmfy5RAAHQzxK43clu3kZmL5eF9VGtYQ==}
- hasBin: true
- peerDependencies:
- typescript: '>=5'
- dependencies:
- chalk: 5.4.1
- commander: 12.1.0
- typescript: 5.7.3
/@solana/options@2.0.0-preview.2:
resolution: {integrity: sha512-FAHqEeH0cVsUOTzjl5OfUBw2cyT8d5Oekx4xcn5hn+NyPAfQJgM3CEThzgRD6Q/4mM5pVUnND3oK/Mt1RzSE/w==}
dependencies:
'@solana/codecs-core': 2.0.0-preview.2
'@solana/codecs-numbers': 2.0.0-preview.2
- dev: false
-
- /@solana/options@2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.7.3):
- resolution: {integrity: sha512-mLUcR9mZ3qfHlmMnREdIFPf9dpMc/Bl66tLSOOWxw4ml5xMT2ohFn7WGqoKcu/UHkT9CrC6+amEdqCNvUqI7AA==}
- peerDependencies:
- typescript: '>=5'
- dependencies:
- '@solana/codecs-core': 2.0.0-rc.1(typescript@5.7.3)
- '@solana/codecs-data-structures': 2.0.0-rc.1(typescript@5.7.3)
- '@solana/codecs-numbers': 2.0.0-rc.1(typescript@5.7.3)
- '@solana/codecs-strings': 2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.7.3)
- '@solana/errors': 2.0.0-rc.1(typescript@5.7.3)
- typescript: 5.7.3
- transitivePeerDependencies:
- - fastestsmallesttextencoderdecoder
/@solana/spl-token-metadata@0.1.4(@solana/web3.js@1.95.0)(fastestsmallesttextencoderdecoder@1.0.22):
resolution: {integrity: sha512-N3gZ8DlW6NWDV28+vCCDJoTqaCZiF/jDUnk3o8GRkAFzHObiR60Bs1gXHBa8zCPdvOwiG6Z3dg5pg7+RW6XNsQ==}
@@ -3618,32 +3658,18 @@ packages:
'@solana/web3.js': 1.95.0
transitivePeerDependencies:
- fastestsmallesttextencoderdecoder
- dev: false
-
- /@solana/spl-token-metadata@0.1.6(@solana/web3.js@1.95.0)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.7.3):
- resolution: {integrity: sha512-7sMt1rsm/zQOQcUWllQX9mD2O6KhSAtY1hFR2hfFwgqfFWzSY9E9GDvFVNYUI1F0iQKcm6HmePU9QbKRXTEBiA==}
- engines: {node: '>=16'}
- peerDependencies:
- '@solana/web3.js': ^1.95.3
- dependencies:
- '@solana/codecs': 2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.7.3)
- '@solana/web3.js': 1.95.0
- transitivePeerDependencies:
- - fastestsmallesttextencoderdecoder
- - typescript
- /@solana/spl-token-metadata@0.1.6(@solana/web3.js@1.98.0)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.7.3):
- resolution: {integrity: sha512-7sMt1rsm/zQOQcUWllQX9mD2O6KhSAtY1hFR2hfFwgqfFWzSY9E9GDvFVNYUI1F0iQKcm6HmePU9QbKRXTEBiA==}
+ /@solana/spl-token-metadata@0.1.4(@solana/web3.js@1.98.0)(fastestsmallesttextencoderdecoder@1.0.22):
+ resolution: {integrity: sha512-N3gZ8DlW6NWDV28+vCCDJoTqaCZiF/jDUnk3o8GRkAFzHObiR60Bs1gXHBa8zCPdvOwiG6Z3dg5pg7+RW6XNsQ==}
engines: {node: '>=16'}
peerDependencies:
- '@solana/web3.js': ^1.95.3
+ '@solana/web3.js': ^1.91.6
dependencies:
- '@solana/codecs': 2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.7.3)
+ '@solana/codecs': 2.0.0-preview.2(fastestsmallesttextencoderdecoder@1.0.22)
+ '@solana/spl-type-length-value': 0.1.0
'@solana/web3.js': 1.98.0
transitivePeerDependencies:
- fastestsmallesttextencoderdecoder
- - typescript
- dev: true
/@solana/spl-token@0.3.11(@solana/web3.js@1.95.0)(fastestsmallesttextencoderdecoder@1.0.22):
resolution: {integrity: sha512-bvohO3rIMSVL24Pb+I4EYTJ6cL82eFpInEXD/I8K8upOGjpqHsKUoAempR/RnUlI1qSFNyFlWJfu6MNUgfbCQQ==}
@@ -3661,27 +3687,8 @@ packages:
- encoding
- fastestsmallesttextencoderdecoder
- utf-8-validate
- dev: false
-
- /@solana/spl-token@0.3.11(@solana/web3.js@1.95.0)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.7.3):
- resolution: {integrity: sha512-bvohO3rIMSVL24Pb+I4EYTJ6cL82eFpInEXD/I8K8upOGjpqHsKUoAempR/RnUlI1qSFNyFlWJfu6MNUgfbCQQ==}
- engines: {node: '>=16'}
- peerDependencies:
- '@solana/web3.js': ^1.88.0
- dependencies:
- '@solana/buffer-layout': 4.0.1
- '@solana/buffer-layout-utils': 0.2.0
- '@solana/spl-token-metadata': 0.1.6(@solana/web3.js@1.95.0)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.7.3)
- '@solana/web3.js': 1.95.0
- buffer: 6.0.3
- transitivePeerDependencies:
- - bufferutil
- - encoding
- - fastestsmallesttextencoderdecoder
- - typescript
- - utf-8-validate
- /@solana/spl-token@0.3.11(@solana/web3.js@1.98.0)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.7.3):
+ /@solana/spl-token@0.3.11(@solana/web3.js@1.98.0)(fastestsmallesttextencoderdecoder@1.0.22):
resolution: {integrity: sha512-bvohO3rIMSVL24Pb+I4EYTJ6cL82eFpInEXD/I8K8upOGjpqHsKUoAempR/RnUlI1qSFNyFlWJfu6MNUgfbCQQ==}
engines: {node: '>=16'}
peerDependencies:
@@ -3689,23 +3696,20 @@ packages:
dependencies:
'@solana/buffer-layout': 4.0.1
'@solana/buffer-layout-utils': 0.2.0
- '@solana/spl-token-metadata': 0.1.6(@solana/web3.js@1.98.0)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.7.3)
+ '@solana/spl-token-metadata': 0.1.4(@solana/web3.js@1.98.0)(fastestsmallesttextencoderdecoder@1.0.22)
'@solana/web3.js': 1.98.0
buffer: 6.0.3
transitivePeerDependencies:
- bufferutil
- encoding
- fastestsmallesttextencoderdecoder
- - typescript
- utf-8-validate
- dev: true
/@solana/spl-type-length-value@0.1.0:
resolution: {integrity: sha512-JBMGB0oR4lPttOZ5XiUGyvylwLQjt1CPJa6qQ5oM+MBCndfjz2TKKkw0eATlLLcYmq1jBVsNlJ2cD6ns2GR7lA==}
engines: {node: '>=16'}
dependencies:
buffer: 6.0.3
- dev: false
/@solana/web3.js@1.95.0:
resolution: {integrity: sha512-iHwJ/HcWrF9qbnI1ctwI1UXHJ0vZXRpnt+lI5UcQIk8WvJNuQ5gV06icxzM6B7ojUES85Q1/FM4jZ49UQ8yZZQ==}
@@ -3802,7 +3806,6 @@ packages:
engines: {node: '>=6'}
dependencies:
defer-to-connect: 1.1.3
- dev: true
/@szmarczak/http-timer@4.0.6:
resolution: {integrity: sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==}
@@ -3861,6 +3864,10 @@ packages:
dev: false
optional: true
+ /@tootallnate/quickjs-emscripten@0.23.0:
+ resolution: {integrity: sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==}
+ dev: false
+
/@truffle/abi-utils@1.0.3:
resolution: {integrity: sha512-AWhs01HCShaVKjml7Z4AbVREr/u4oiWxCcoR7Cktm0mEvtT04pvnxW5xB/cI4znRkrbPdFQlFt67kgrAjesYkw==}
engines: {node: ^16.20 || ^18.16 || >=20}
@@ -4049,23 +4056,34 @@ packages:
/@types/bn.js@5.1.5:
resolution: {integrity: sha512-V46N0zwKRF5Q00AZ6hWtN0T8gGmDUaUzLWQvHFo5yThtVwK/VCenFY3wXVbOvNfajEpsTfQM4IN9k/d6gUVX3A==}
dependencies:
- '@types/node': 14.18.63
+ '@types/node': 20.17.16
dev: true
/@types/bn.js@5.1.6:
resolution: {integrity: sha512-Xh8vSwUeMKeYYrj3cX4lGQgFSF/N03r+tv4AiLl1SucqV+uTQpxRcnM8AkXKHwYP9ZPXOYXRr2KPXpVlIvqh9w==}
dependencies:
- '@types/node': 14.18.63
+ '@types/node': 20.17.16
+
+ /@types/body-parser@1.19.5:
+ resolution: {integrity: sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==}
+ dependencies:
+ '@types/connect': 3.4.38
+ '@types/node': 22.10.10
+ dev: true
/@types/cacheable-request@6.0.3:
resolution: {integrity: sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw==}
dependencies:
'@types/http-cache-semantics': 4.0.4
'@types/keyv': 3.1.4
- '@types/node': 14.18.63
+ '@types/node': 20.17.16
'@types/responselike': 1.0.3
dev: true
+ /@types/caseless@0.12.5:
+ resolution: {integrity: sha512-hWtVTC2q7hc7xZ/RLbxapMvDMgUnDvKvMOpKal4DrMyfGBUfB1oKaZlIRr6mJL+If3bAP6sV/QneGzF6tJjZDg==}
+ dev: false
+
/@types/chai@4.3.16:
resolution: {integrity: sha512-PatH4iOdyh3MyWtmHVFXLWCCIhUbopaltqddG9BzB+gMIzee2MJrvd+jouii9Z3wzQJruGWAm7WOMjgfG8hQlQ==}
dev: true
@@ -4085,6 +4103,24 @@ packages:
dependencies:
'@types/node': 20.17.16
+ /@types/express-serve-static-core@5.0.5:
+ resolution: {integrity: sha512-GLZPrd9ckqEBFMcVM/qRFAP0Hg3qiVEojgEFsx/N/zKXsBzbGF6z5FBDpZ0+Xhp1xr+qRZYjfGr1cWHB9oFHSA==}
+ dependencies:
+ '@types/node': 22.10.10
+ '@types/qs': 6.9.18
+ '@types/range-parser': 1.2.7
+ '@types/send': 0.17.4
+ dev: true
+
+ /@types/express@5.0.0:
+ resolution: {integrity: sha512-DvZriSMehGHL1ZNLzi6MidnsDhUZM/x2pRdDIKdwbUNqqwHxMlRdkxtn6/EPKyqKpHqTl/4nRZsRNLpZxZRpPQ==}
+ dependencies:
+ '@types/body-parser': 1.19.5
+ '@types/express-serve-static-core': 5.0.5
+ '@types/qs': 6.9.18
+ '@types/serve-static': 1.15.7
+ dev: true
+
/@types/form-data@0.0.33:
resolution: {integrity: sha512-8BSvG1kGm83cyJITQMZSulnl6QV8jqAGreJsc5tPu1Jq0vTSOiY/k24Wx82JRpWwZSqrala6sd5rWi6aNXvqcw==}
dependencies:
@@ -4095,13 +4131,17 @@ packages:
resolution: {integrity: sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==}
dependencies:
'@types/minimatch': 5.1.2
- '@types/node': 14.18.63
+ '@types/node': 20.17.16
dev: true
/@types/http-cache-semantics@4.0.4:
resolution: {integrity: sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==}
dev: true
+ /@types/http-errors@2.0.4:
+ resolution: {integrity: sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==}
+ dev: true
+
/@types/json-schema@7.0.15:
resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==}
dev: true
@@ -4113,8 +4153,7 @@ packages:
/@types/keyv@3.1.4:
resolution: {integrity: sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==}
dependencies:
- '@types/node': 14.18.63
- dev: true
+ '@types/node': 20.17.16
/@types/lodash.values@4.3.9:
resolution: {integrity: sha512-IJ20OEfqNwm3k8ENwoM3q0yOs4UMpgtD4GqxB4lwBHToGthHWqhyh5DdSgQjioocz0QK2SSBkJfCq95ZTV8BTw==}
@@ -4134,6 +4173,10 @@ packages:
/@types/lru-cache@5.1.1:
resolution: {integrity: sha512-ssE3Vlrys7sdIzs5LOxCzTVMsU7i9oa/IaW92wF32JFb3CVczqOkru2xspuKczHEbG3nvmPY7IFqVmGGHdNbYw==}
+ /@types/mime@1.3.5:
+ resolution: {integrity: sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==}
+ dev: true
+
/@types/minimatch@5.1.2:
resolution: {integrity: sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==}
dev: true
@@ -4141,7 +4184,7 @@ packages:
/@types/mkdirp@0.5.2:
resolution: {integrity: sha512-U5icWpv7YnZYGsN4/cmh3WD2onMY0aJIiTE6+51TwJCttdHvtCYmkBNOobHlXwrJRL0nkH9jH4kD+1FAdMN4Tg==}
dependencies:
- '@types/node': 14.18.63
+ '@types/node': 20.17.16
dev: true
/@types/mocha@8.2.3:
@@ -4151,7 +4194,7 @@ packages:
/@types/node-fetch@2.6.11:
resolution: {integrity: sha512-24xFj9R5+rfQJLRyM56qh+wnVSYhyXC2tkoBndtY0U+vubqNsYXGjufB2nn8Q6gt0LrARwL6UBtMCSVCwl4B1g==}
dependencies:
- '@types/node': 14.18.63
+ '@types/node': 20.17.16
form-data: 4.0.0
dev: true
@@ -4167,6 +4210,7 @@ packages:
/@types/node@14.18.63:
resolution: {integrity: sha512-fAtCfv4jJg+ExtXhvCkCqUKZ+4ok/JQk01qDKhL5BDDoS3AxKXhV5/MAVUZyQnSEd2GT92fkgZl0pz0Q0AzcIQ==}
+ dev: true
/@types/node@18.19.74:
resolution: {integrity: sha512-HMwEkkifei3L605gFdV+/UwtpxP6JSzM+xFk2Ia6DNFSwSVBRh9qp5Tgf4lNFOMfPVuU0WnkcWpXZpgn5ufO4A==}
@@ -4187,10 +4231,14 @@ packages:
resolution: {integrity: sha512-tktOkFUA4kXx2hhhrB8bIFb5TbwzS4uOhKEmwiD+NoiL0qtP2OQ9mFldbgD4dV1djrlBYP6eBuQZiWjuHUpqFw==}
dev: true
+ /@types/nunjucks@3.2.6:
+ resolution: {integrity: sha512-pHiGtf83na1nCzliuAdq8GowYiXvH5l931xZ0YEHaLMNFgynpEqx+IPStlu7UaDkehfvl01e4x/9Tpwhy7Ue3w==}
+ dev: false
+
/@types/pbkdf2@3.1.2:
resolution: {integrity: sha512-uRwJqmiXmh9++aSu1VNEn3iIxWOhd8AHXNSdlaLfdAAdSTY9jYVeGWnzejM3dvrkbqE3/hyQkQQ29IFATEGlew==}
dependencies:
- '@types/node': 14.18.63
+ '@types/node': 20.17.16
/@types/prettier@2.7.3:
resolution: {integrity: sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA==}
@@ -4204,26 +4252,53 @@ packages:
resolution: {integrity: sha512-kK7dgTYDyGqS+e2Q4aK9X3D7q234CIZ1Bv0q/7Z5IwRDoADNU81xXJK/YVyLbLTZCoIwUoDoffFeF+p/eIklAA==}
dev: true
+ /@types/range-parser@1.2.7:
+ resolution: {integrity: sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==}
+ dev: true
+
+ /@types/request@2.48.12:
+ resolution: {integrity: sha512-G3sY+NpsA9jnwm0ixhAFQSJ3Q9JkpLZpJbI3GMv0mIAT0y3mRabYeINzal5WOChIiaTEGQYlHOKgkaM9EisWHw==}
+ dependencies:
+ '@types/caseless': 0.12.5
+ '@types/node': 22.10.10
+ '@types/tough-cookie': 4.0.5
+ form-data: 2.5.2
+ dev: false
+
/@types/resolve@0.0.8:
resolution: {integrity: sha512-auApPaJf3NPfe18hSoJkp8EbZzer2ISk7o8mCC3M9he/a04+gbMF97NkpD2S8riMGvm4BMRI59/SZQSaLTKpsQ==}
dependencies:
- '@types/node': 14.18.63
+ '@types/node': 20.17.16
dev: true
/@types/responselike@1.0.3:
resolution: {integrity: sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw==}
dependencies:
- '@types/node': 14.18.63
- dev: true
+ '@types/node': 20.17.16
/@types/secp256k1@4.0.6:
resolution: {integrity: sha512-hHxJU6PAEUn0TP4S/ZOzuTUvJWuZ6eIKeNKb5RBpODvSl6hp1Wrw4s7ATY50rklRCScUDpHzVA/DQdSjJ3UoYQ==}
dependencies:
- '@types/node': 14.18.63
+ '@types/node': 20.17.16
/@types/seedrandom@3.0.1:
resolution: {integrity: sha512-giB9gzDeiCeloIXDgzFBCgjj1k4WxcDrZtGl6h1IqmUPlxF+Nx8Ve+96QCyDZ/HseB/uvDsKbpib9hU5cU53pw==}
+ /@types/send@0.17.4:
+ resolution: {integrity: sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==}
+ dependencies:
+ '@types/mime': 1.3.5
+ '@types/node': 22.10.10
+ dev: true
+
+ /@types/serve-static@1.15.7:
+ resolution: {integrity: sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==}
+ dependencies:
+ '@types/http-errors': 2.0.4
+ '@types/node': 22.10.10
+ '@types/send': 0.17.4
+ dev: true
+
/@types/sinon-chai@3.2.12:
resolution: {integrity: sha512-9y0Gflk3b0+NhQZ/oxGtaAJDvRywCa5sIyaVnounqLvmf93yBF4EgIRspePtkMs3Tr844nCclYMlcCNmLCvjuQ==}
dependencies:
@@ -4241,6 +4316,10 @@ packages:
resolution: {integrity: sha512-mQkU2jY8jJEF7YHjHvsQO8+3ughTL1mcnn96igfhONmR+fUPSKIkefQYpSe8bsly2Ep7oQbn/6VG5/9/0qcArQ==}
dev: true
+ /@types/tough-cookie@4.0.5:
+ resolution: {integrity: sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==}
+ dev: false
+
/@types/triple-beam@1.3.5:
resolution: {integrity: sha512-6WaYesThRMCl19iryMYP7/x2OVgCtbIVflDGFpWnb9irXI3UjYE4AzmYuiUKY1AJstGijoY+MgUszMgRxIYTYw==}
@@ -4255,7 +4334,7 @@ packages:
/@types/ws@8.5.10:
resolution: {integrity: sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A==}
dependencies:
- '@types/node': 22.10.10
+ '@types/node': 20.17.16
/@types/ws@8.5.14:
resolution: {integrity: sha512-bd/YFLW+URhBzMXurx7lWByOu+xzU9+kb3RboOteXYDfW+tr+JZa99OyNmPINEGB/ahzKrEuc8rcv4gnpJmxTw==}
@@ -4566,7 +4645,7 @@ packages:
resolution: {integrity: sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==}
dev: true
- /@wormhole-foundation/relayer-engine@0.3.2(@bull-board/ui@5.21.0)(@improbable-eng/grpc-web@0.15.0)(@types/node@20.17.16)(fastestsmallesttextencoderdecoder@1.0.22)(google-protobuf@3.21.4)(typescript@5.7.3):
+ /@wormhole-foundation/relayer-engine@0.3.2(@bull-board/ui@5.21.0)(@improbable-eng/grpc-web@0.15.0)(@types/node@22.10.10)(fastestsmallesttextencoderdecoder@1.0.22)(google-protobuf@3.21.4)(typescript@5.7.3):
resolution: {integrity: sha512-6CAGZdxDpPZph+Gx1Tob5wEarEzvD27G7khoGhB9sc8KiOhRz8zDiBspFfLetzfBEHMiTyvAOibETV5G0ULilA==}
dependencies:
'@bull-board/api': 5.21.0(@bull-board/ui@5.21.0)
@@ -4577,7 +4656,7 @@ packages:
'@improbable-eng/grpc-web-node-http-transport': 0.15.0(@improbable-eng/grpc-web@0.15.0)
'@mysten/sui.js': 0.32.2
'@sei-js/core': 1.5.0
- '@xlabs-xyz/wallet-monitor': 0.2.16(@types/node@20.17.16)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.7.3)
+ '@xlabs-xyz/wallet-monitor': 0.2.16(@types/node@22.10.10)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.7.3)
bech32: 2.0.0
bullmq: 3.15.8
ethers: 5.7.2
@@ -4664,7 +4743,7 @@ packages:
dependencies:
'@bull-board/api': 5.23.0(@bull-board/ui@5.23.0)
'@bull-board/koa': 5.23.0
- '@certusone/wormhole-sdk': 0.10.18(fastestsmallesttextencoderdecoder@1.0.22)(google-protobuf@3.21.4)(typescript@5.7.3)
+ '@certusone/wormhole-sdk': 0.10.18(fastestsmallesttextencoderdecoder@1.0.22)(google-protobuf@3.21.4)
'@certusone/wormhole-spydk': 0.0.1
'@datastructures-js/queue': 4.2.3
'@improbable-eng/grpc-web-node-http-transport': 0.15.0(@improbable-eng/grpc-web@0.15.0)
@@ -4757,7 +4836,7 @@ packages:
engines: {node: '>=8'}
requiresBuild: true
dependencies:
- tslib: 2.6.3
+ tslib: 2.8.1
optional: true
/@wry/context@0.7.4:
@@ -4765,7 +4844,7 @@ packages:
engines: {node: '>=8'}
requiresBuild: true
dependencies:
- tslib: 2.6.3
+ tslib: 2.8.1
optional: true
/@wry/equality@0.5.7:
@@ -4773,7 +4852,7 @@ packages:
engines: {node: '>=8'}
requiresBuild: true
dependencies:
- tslib: 2.6.3
+ tslib: 2.8.1
optional: true
/@wry/trie@0.5.0:
@@ -4781,7 +4860,7 @@ packages:
engines: {node: '>=8'}
requiresBuild: true
dependencies:
- tslib: 2.6.3
+ tslib: 2.8.1
optional: true
/@xlabs-xyz/wallet-monitor@0.2.16(@types/node@20.17.16)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.7.3):
@@ -4789,7 +4868,7 @@ packages:
dependencies:
'@ethersproject/bignumber': 5.7.0
'@mysten/sui.js': 0.32.2
- '@solana/spl-token': 0.3.11(@solana/web3.js@1.95.0)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.7.3)
+ '@solana/spl-token': 0.3.11(@solana/web3.js@1.95.0)(fastestsmallesttextencoderdecoder@1.0.22)
'@solana/web3.js': 1.95.0
bluebird: 3.7.2
bs58: 5.0.0
@@ -4813,6 +4892,38 @@ packages:
- supports-color
- typescript
- utf-8-validate
+ dev: true
+
+ /@xlabs-xyz/wallet-monitor@0.2.16(@types/node@22.10.10)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.7.3):
+ resolution: {integrity: sha512-Fup24DcONFy3o5lrJP3i5gc5XXj7675gWhco3JkweWTFj86c17UrXYQOhZF1Z09b7WYt4rnXZx+wQ4W19HzOoQ==}
+ dependencies:
+ '@ethersproject/bignumber': 5.7.0
+ '@mysten/sui.js': 0.32.2
+ '@solana/spl-token': 0.3.11(@solana/web3.js@1.95.0)(fastestsmallesttextencoderdecoder@1.0.22)
+ '@solana/web3.js': 1.95.0
+ bluebird: 3.7.2
+ bs58: 5.0.0
+ ethers: 5.7.2
+ google-protobuf: 3.21.2
+ koa: 2.15.3
+ koa-router: 12.0.1
+ nice-grpc: 2.1.9
+ prom-client: 14.2.0
+ ts-node: 10.9.2(@types/node@22.10.10)(typescript@5.7.3)
+ ts-proto: 1.181.0
+ winston: 3.13.1
+ zod: 3.23.8
+ transitivePeerDependencies:
+ - '@swc/core'
+ - '@swc/wasm'
+ - '@types/node'
+ - bufferutil
+ - encoding
+ - fastestsmallesttextencoderdecoder
+ - supports-color
+ - typescript
+ - utf-8-validate
+ dev: false
/@xpla/xpla.js@0.2.3:
resolution: {integrity: sha512-Tfk7hCGWXtwr08reY3Pi6dmzIqFbzri9jcyzJdfNmdo4cN0PMwpRJuZZcPmtxiIUnNef3AN1E/6nJUD5MKniuA==}
@@ -4852,6 +4963,10 @@ packages:
jsonparse: 1.3.1
through: 2.3.8
+ /a-sync-waterfall@1.0.1:
+ resolution: {integrity: sha512-RYTOHHdWipFUliRFMCS4X2Yn2X8M87V/OpSqWzKKOGhzqyUxzyVmhHDH9sAvG+ZuQf/TAOFsLCpMw09I1ufUnA==}
+ dev: false
+
/abbrev@1.0.9:
resolution: {integrity: sha512-LEyx4aLEC3x6T0UguF6YILf+ntvmOaWsVfENmIW0E9H09vKlLDGelMjjSm0jkDHALj8A8quZ/HapKNigzwge+Q==}
dev: true
@@ -4996,7 +5111,6 @@ packages:
/adm-zip@0.4.16:
resolution: {integrity: sha512-TFi4HBKSGfIKsK5YCkKaaFG2m4PEDyViZmEwof3MTIgzimHLto6muaHVpbrljdIvIrFZzEq/p4nafOeLcYegrg==}
engines: {node: '>=0.3.0'}
- dev: true
/aes-js@3.0.0:
resolution: {integrity: sha512-H7wUZRn8WpTq9jocdxQ2c8x2sKo9ZVmzfRE13GiNJXfp7NcKYEdvl3vspKjXox6RIG2VtaRe4JFvxG4rqp2Zuw==}
@@ -5016,6 +5130,11 @@ packages:
transitivePeerDependencies:
- supports-color
+ /agent-base@7.1.3:
+ resolution: {integrity: sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==}
+ engines: {node: '>= 14'}
+ dev: false
+
/agentkeepalive@4.5.0:
resolution: {integrity: sha512-5GG/5IbQQpC9FpkRGsSvZI5QYeSCzlJHdpBQntCsuTOxhKD8lqKhrleg2Yi7yvMIf82Ycmmqln9U8V9qwEiJew==}
engines: {node: '>= 8.0.0'}
@@ -5045,7 +5164,6 @@ packages:
fast-deep-equal: 1.1.0
fast-json-stable-stringify: 2.1.0
json-schema-traverse: 0.3.1
- dev: true
/ajv@6.12.6:
resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==}
@@ -5054,7 +5172,6 @@ packages:
fast-json-stable-stringify: 2.1.0
json-schema-traverse: 0.4.1
uri-js: 4.4.1
- dev: true
/ajv@8.16.0:
resolution: {integrity: sha512-F0twR8U1ZU67JIEtekUcLkXkoO5mMMmgGD8sK/xUFzJ805jxHQl92hImFAqqXMyMYjSPOyUPAwHYhB72g5sTXw==}
@@ -5065,15 +5182,6 @@ packages:
uri-js: 4.4.1
dev: true
- /ajv@8.17.1:
- resolution: {integrity: sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==}
- dependencies:
- fast-deep-equal: 3.1.3
- fast-uri: 3.0.6
- json-schema-traverse: 1.0.0
- require-from-string: 2.0.2
- dev: true
-
/algo-msgpack-with-bigint@2.1.1:
resolution: {integrity: sha512-F1tGh056XczEaEAqu7s+hlZUDWwOBT70Eq0lfMpBP2YguSQVyxRbprLq5rELXKQOyOaixTWYhMeMQMzP0U5FoQ==}
engines: {node: '>= 10'}
@@ -5091,7 +5199,6 @@ packages:
json-bigint: 1.0.0
tweetnacl: 1.0.3
vlq: 2.0.4
- dev: true
/algosdk@2.8.0:
resolution: {integrity: sha512-yjDH/VbQ689hxmn4PFbfXQrn4VZbYCGGzI/RD4ccA0yr55qT/TyAtR/dnq4XXX2pwCKNHbxOfantaJ5kTiwuMQ==}
@@ -5119,12 +5226,10 @@ packages:
resolution: {integrity: sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==}
dependencies:
string-width: 4.2.3
- dev: true
/ansi-colors@4.1.3:
resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==}
engines: {node: '>=6'}
- dev: true
/ansi-escapes@3.2.0:
resolution: {integrity: sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==}
@@ -5136,17 +5241,14 @@ packages:
engines: {node: '>=8'}
dependencies:
type-fest: 0.21.3
- dev: true
/ansi-regex@2.1.1:
resolution: {integrity: sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==}
engines: {node: '>=0.10.0'}
- dev: true
/ansi-regex@3.0.1:
resolution: {integrity: sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==}
engines: {node: '>=4'}
- dev: true
/ansi-regex@5.0.1:
resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==}
@@ -5187,11 +5289,6 @@ packages:
engines: {node: '>=16'}
dev: true
- /antlr4@4.13.2:
- resolution: {integrity: sha512-QiVbZhyy4xAZ17UPEuG3YTOt8ZaoeOR1CvEAqrEsDBsOqINslaB147i9xqljZqoyf5S+EUlGStaj+t22LT9MOg==}
- engines: {node: '>=16'}
- dev: true
-
/antlr4ts@0.5.0-alpha.4:
resolution: {integrity: sha512-WPQDt1B74OfPv/IMS2ekXAKkTZIHl88uMetg6q3OTqgFxZ/dxDXI0EWLyZid/1Pe6hTftyg5N7gel5wNAGxXyQ==}
dev: true
@@ -5212,7 +5309,6 @@ packages:
dependencies:
normalize-path: 3.0.0
picomatch: 2.3.1
- dev: true
/apicache@1.6.3:
resolution: {integrity: sha512-jS3VfUFpQ9BesFQZcdd1vVYg3ZsO2kGPmTJHqycIYPAQs54r74CRiyj8DuzJpwzLwIfCBYzh4dy9Jt8xYbo27w==}
@@ -5275,7 +5371,6 @@ packages:
/argparse@2.0.1:
resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==}
- dev: true
/argv@0.0.2:
resolution: {integrity: sha512-dEamhpPEwRUBpLNHeuCm/v+g0anFByHahxodVO/BbAarHVBBg2MccCwf9K+o1Pof+2btdnkJelYVUWjW/VrATw==}
@@ -5459,12 +5554,11 @@ packages:
/asap@2.0.6:
resolution: {integrity: sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==}
- dev: true
/asn1.js@4.10.1:
resolution: {integrity: sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==}
dependencies:
- bn.js: 4.12.0
+ bn.js: 4.12.1
inherits: 2.0.4
minimalistic-assert: 1.0.1
dev: true
@@ -5473,12 +5567,10 @@ packages:
resolution: {integrity: sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==}
dependencies:
safer-buffer: 2.1.2
- dev: true
/assert-plus@1.0.0:
resolution: {integrity: sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==}
engines: {node: '>=0.8'}
- dev: true
/assertion-error@1.1.0:
resolution: {integrity: sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==}
@@ -5493,6 +5585,13 @@ packages:
resolution: {integrity: sha512-XHusKxKz3zoYk1ic8Un640joHbFMhbqneyoZfoKnEGtf2ey9Uh/IdpcQplODdO/kENaMIWsD0nJm4+wX3UNLHA==}
dev: true
+ /ast-types@0.13.4:
+ resolution: {integrity: sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==}
+ engines: {node: '>=4'}
+ dependencies:
+ tslib: 2.8.1
+ dev: false
+
/astral-regex@2.0.0:
resolution: {integrity: sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==}
engines: {node: '>=8'}
@@ -5569,11 +5668,16 @@ packages:
/aws-sign2@0.7.0:
resolution: {integrity: sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==}
- dev: true
/aws4@1.13.0:
resolution: {integrity: sha512-3AungXC4I8kKsS9PuS4JH2nc+0bVY/mjgrephHTIi8fpEeGsTHBUJeosp0Wc1myYMElmD0B3Oc4XL/HVJ4PV2g==}
- dev: true
+
+ /axios@0.21.4:
+ resolution: {integrity: sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==}
+ dependencies:
+ follow-redirects: 1.15.6(debug@4.4.0)
+ transitivePeerDependencies:
+ - debug
/axios@0.21.4(debug@4.3.5):
resolution: {integrity: sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==}
@@ -5581,25 +5685,26 @@ packages:
follow-redirects: 1.15.6(debug@4.3.5)
transitivePeerDependencies:
- debug
+ dev: true
/axios@0.24.0:
resolution: {integrity: sha512-Q6cWsys88HoPgAaFAVUb0WpPk0O8iTeisR9IMqy9G8AbO4NlpVknrnQS03zzF9PGAWgO3cgletO3VjV/P7VztA==}
dependencies:
- follow-redirects: 1.15.9(debug@4.4.0)
+ follow-redirects: 1.15.9
transitivePeerDependencies:
- debug
/axios@0.26.1:
resolution: {integrity: sha512-fPwcX4EvnSHuInCMItEhAGnaSEXRBjtzh9fOtsE6E1G6p7vl7edEeZe11QHf18+6+9gR5PbKV/sGKNaD8YaMeA==}
dependencies:
- follow-redirects: 1.15.9(debug@4.4.0)
+ follow-redirects: 1.15.9
transitivePeerDependencies:
- debug
/axios@0.27.2:
resolution: {integrity: sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==}
dependencies:
- follow-redirects: 1.15.9(debug@4.4.0)
+ follow-redirects: 1.15.9
form-data: 4.0.0
transitivePeerDependencies:
- debug
@@ -5607,7 +5712,7 @@ packages:
/axios@0.28.1:
resolution: {integrity: sha512-iUcGA5a7p0mVb4Gm/sy+FSECNkPFT4y7wt6OM/CDpO/OnNCvSs3PoMG8ibrC9jRoGYU0gUK5pXVC4NPXq6lHRQ==}
dependencies:
- follow-redirects: 1.15.9(debug@4.4.0)
+ follow-redirects: 1.15.9
form-data: 4.0.1
proxy-from-env: 1.1.0
transitivePeerDependencies:
@@ -5616,7 +5721,7 @@ packages:
/axios@1.7.9:
resolution: {integrity: sha512-LhLcE7Hbiryz8oMDdDptSrWowmB4Bl6RCt6sIJKpRB4XtVf0iEgewX3au/pJqm+Py1kCASkb/FFKjxQaLtxJvw==}
dependencies:
- follow-redirects: 1.15.9(debug@4.4.0)
+ follow-redirects: 1.15.9
form-data: 4.0.1
proxy-from-env: 1.1.0
transitivePeerDependencies:
@@ -6230,11 +6335,15 @@ packages:
pascalcase: 0.1.1
dev: true
+ /basic-ftp@5.0.5:
+ resolution: {integrity: sha512-4Bcg1P8xhUuqcii/S0Z9wiHIrQVPMermM1any+MX5GeGD7faD3/msQUDGLol9wOcz4/jbg/WJnGqoJF6LiBdtg==}
+ engines: {node: '>=10.0.0'}
+ dev: false
+
/bcrypt-pbkdf@1.0.2:
resolution: {integrity: sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==}
dependencies:
tweetnacl: 0.14.5
- dev: true
/bech32@1.1.4:
resolution: {integrity: sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==}
@@ -6242,6 +6351,36 @@ packages:
/bech32@2.0.0:
resolution: {integrity: sha512-LcknSilhIGatDAsY1ak2I8VtGaHNhgMSYVxFrGLXv+xLHytaKZKcaUJJUE7qmBr7h33o5YQwP55pMI0xmkpJwg==}
+ /better-ajv-errors@0.6.7(ajv@5.5.2):
+ resolution: {integrity: sha512-PYgt/sCzR4aGpyNy5+ViSQ77ognMnWq7745zM+/flYO4/Yisdtp9wDQW2IKCyVYPUxQt3E/b5GBSwfhd1LPdlg==}
+ peerDependencies:
+ ajv: 4.11.8 - 6
+ dependencies:
+ '@babel/code-frame': 7.24.7
+ '@babel/runtime': 7.26.0
+ ajv: 5.5.2
+ chalk: 2.4.2
+ core-js: 3.40.0
+ json-to-ast: 2.1.0
+ jsonpointer: 4.1.0
+ leven: 3.1.0
+ dev: false
+
+ /better-ajv-errors@0.6.7(ajv@6.12.6):
+ resolution: {integrity: sha512-PYgt/sCzR4aGpyNy5+ViSQ77ognMnWq7745zM+/flYO4/Yisdtp9wDQW2IKCyVYPUxQt3E/b5GBSwfhd1LPdlg==}
+ peerDependencies:
+ ajv: 4.11.8 - 6
+ dependencies:
+ '@babel/code-frame': 7.24.7
+ '@babel/runtime': 7.26.0
+ ajv: 6.12.6
+ chalk: 2.4.2
+ core-js: 3.40.0
+ json-to-ast: 2.1.0
+ jsonpointer: 4.1.0
+ leven: 3.1.0
+ dev: false
+
/better-sqlite3@9.6.0:
resolution: {integrity: sha512-yR5HATnqeYNVnkaUTf4bOP2dJSnyhP4puJN/QPRyx4YkBEEUxib422n2XzPqDEHjQQqazoYoADdAm5vE15+dAQ==}
requiresBuild: true
@@ -6280,7 +6419,6 @@ packages:
/binary-extensions@2.3.0:
resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==}
engines: {node: '>=8'}
- dev: true
/binary-parser@2.2.1:
resolution: {integrity: sha512-5ATpz/uPDgq5GgEDxTB4ouXCde7q2lqAQlSdBRQVl/AJnxmQmhIfyxJx+0MGu//D5rHQifkfGbWWlaysG0o9NA==}
@@ -6399,7 +6537,6 @@ packages:
unpipe: 1.0.0
transitivePeerDependencies:
- supports-color
- dev: true
/boolbase@1.0.0:
resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==}
@@ -6412,6 +6549,20 @@ packages:
bs58: 4.0.1
text-encoding-utf-8: 1.0.2
+ /boxen@4.2.0:
+ resolution: {integrity: sha512-eB4uT9RGzg2odpER62bBwSLvUeGC+WbRjjyyFhGsKnc8wp/m0+hQsMUvUe3H2V0D5vw0nBdO1hCJoZo5mKeuIQ==}
+ engines: {node: '>=8'}
+ dependencies:
+ ansi-align: 3.0.1
+ camelcase: 5.3.1
+ chalk: 3.0.0
+ cli-boxes: 2.2.1
+ string-width: 4.2.3
+ term-size: 2.2.1
+ type-fest: 0.8.1
+ widest-line: 3.1.0
+ dev: false
+
/boxen@5.1.2:
resolution: {integrity: sha512-9gYgQKXx+1nP8mP7CzFyaUARhg7D3n1dF/FnErWmu9l6JvGpNUN278h0aSb+QjoiKSWG+iZ3uHrcqk0qrY9RQQ==}
engines: {node: '>=10'}
@@ -6424,7 +6575,6 @@ packages:
type-fest: 0.20.2
widest-line: 3.1.0
wrap-ansi: 7.0.0
- dev: true
/brace-expansion@1.1.11:
resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==}
@@ -6470,7 +6620,6 @@ packages:
engines: {node: '>=8'}
dependencies:
fill-range: 7.1.1
- dev: true
/brorand@1.1.0:
resolution: {integrity: sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==}
@@ -6484,7 +6633,6 @@ packages:
/browser-stdout@1.3.1:
resolution: {integrity: sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==}
- dev: true
/browserify-aes@1.2.0:
resolution: {integrity: sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==}
@@ -6564,7 +6712,6 @@ packages:
/buffer-from@1.1.2:
resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==}
- dev: true
/buffer-layout@1.2.2:
resolution: {integrity: sha512-kWSuLN694+KTk8SrYvCqwP2WcgQjoRCiF5b4QDvkkz8EmgD+aWAIceGFKMIAdmF/pH+vpgNV3d3kAKorcdAmWA==}
@@ -6735,7 +6882,6 @@ packages:
lowercase-keys: 2.0.0
normalize-url: 4.5.1
responselike: 1.0.2
- dev: true
/cacheable-request@7.0.4:
resolution: {integrity: sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg==}
@@ -6763,7 +6909,6 @@ packages:
dependencies:
es-errors: 1.3.0
function-bind: 1.1.2
- dev: true
/call-bind@1.0.7:
resolution: {integrity: sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==}
@@ -6791,7 +6936,10 @@ packages:
dependencies:
call-bind-apply-helpers: 1.0.1
get-intrinsic: 1.2.7
- dev: true
+
+ /call-me-maybe@1.0.2:
+ resolution: {integrity: sha512-HpX65o1Hnr9HH25ojC1YGs7HCQLq0GCOibSaWER0eNpgJ/Z1MZv2mTc7+xh6WOPxbRVcmgbv4hGU+uSQ/2xFZQ==}
+ dev: false
/callsites@3.1.0:
resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==}
@@ -6822,7 +6970,6 @@ packages:
/camelcase@6.3.0:
resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==}
engines: {node: '>=10'}
- dev: true
/caniuse-lite@1.0.30001695:
resolution: {integrity: sha512-vHyLade6wTgI2u1ec3WQBxv+2BrTERV28UXQu9LO6lZ9pYeMk34vjXFLOxo1A4UBA8XTL4njRQZdno/yYaSmWw==}
@@ -6846,7 +6993,6 @@ packages:
/caseless@0.12.0:
resolution: {integrity: sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==}
- dev: true
/catering@2.1.1:
resolution: {integrity: sha512-K7Qy8O9p76sL3/3m7/zLKbRkyOlSZAgzEaLhyj2mXS8PsCud2Eo4hAb8aLtZqHh0QGqLcb9dlJSu6lHRVENm1w==}
@@ -6906,6 +7052,14 @@ packages:
escape-string-regexp: 1.0.5
supports-color: 5.5.0
+ /chalk@3.0.0:
+ resolution: {integrity: sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==}
+ engines: {node: '>=8'}
+ dependencies:
+ ansi-styles: 4.3.0
+ supports-color: 7.2.0
+ dev: false
+
/chalk@4.1.2:
resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==}
engines: {node: '>=10'}
@@ -6916,11 +7070,6 @@ packages:
/chalk@5.3.0:
resolution: {integrity: sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==}
engines: {node: ^12.17.0 || ^14.13 || >=16.0.0}
- dev: false
-
- /chalk@5.4.1:
- resolution: {integrity: sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==}
- engines: {node: ^12.17.0 || ^14.13 || >=16.0.0}
/change-case@3.0.2:
resolution: {integrity: sha512-Mww+SLF6MZ0U6kdg11algyKd5BARbyM4TbFBepwowYSR5ClfQGCGtxNXgykpN0uF/bstWeaGDT4JWaDh8zWAHA==}
@@ -6945,6 +7094,10 @@ packages:
upper-case-first: 1.1.2
dev: true
+ /chardet@0.7.0:
+ resolution: {integrity: sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==}
+ dev: false
+
/charenc@0.0.2:
resolution: {integrity: sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA==}
dev: true
@@ -7021,14 +7174,12 @@ packages:
readdirp: 3.6.0
optionalDependencies:
fsevents: 2.3.3
- dev: true
/chokidar@4.0.3:
resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==}
engines: {node: '>= 14.16.0'}
dependencies:
readdirp: 4.1.1
- dev: true
/chownr@1.1.4:
resolution: {integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==}
@@ -7040,7 +7191,6 @@ packages:
/ci-info@2.0.0:
resolution: {integrity: sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==}
- dev: true
/cids@0.7.5:
resolution: {integrity: sha512-zT7mPeghoWAu+ppn8+BS1tQ5qGmbMfB4AregnQjA/qHY3GC1m1ptI9GkWNlgeu38r7CuRdXB47uY2XgAYt6QVA==}
@@ -7082,7 +7232,18 @@ packages:
/cli-boxes@2.2.1:
resolution: {integrity: sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==}
engines: {node: '>=6'}
- dev: true
+
+ /cli-cursor@3.1.0:
+ resolution: {integrity: sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==}
+ engines: {node: '>=8'}
+ dependencies:
+ restore-cursor: 3.1.0
+ dev: false
+
+ /cli-spinners@2.9.2:
+ resolution: {integrity: sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==}
+ engines: {node: '>=6'}
+ dev: false
/cli-table3@0.5.1:
resolution: {integrity: sha512-7Qg2Jrep1S/+Q3EceiZtQcDPWxhAvBw+ERf1162v4sikJrvojMHFqXt8QIVha8UlH9rgU0BeWPytZ9/TzYqlUw==}
@@ -7110,6 +7271,19 @@ packages:
colors: 1.0.3
dev: true
+ /cli-width@3.0.0:
+ resolution: {integrity: sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==}
+ engines: {node: '>= 10'}
+ dev: false
+
+ /cli@1.0.1:
+ resolution: {integrity: sha512-41U72MB56TfUMGndAKK8vJ78eooOD4Z5NOL4xEfjc0c23s+6EYKXlXsmACBVclLP1yOfWCgEganVzddVrSNoTg==}
+ engines: {node: '>=0.2.5'}
+ dependencies:
+ exit: 0.1.2
+ glob: 7.2.3
+ dev: false
+
/cliui@3.2.0:
resolution: {integrity: sha512-0yayqDxWQbqk3ojkYqUKqaAQ6AfNKeKWRNA8kR0WXzAsdHpP4BIaOmMAG87JGuO6qcobyW4GjxHd9PmhEd+T9w==}
dependencies:
@@ -7124,7 +7298,6 @@ packages:
string-width: 2.1.1
strip-ansi: 4.0.0
wrap-ansi: 2.1.0
- dev: true
/cliui@7.0.4:
resolution: {integrity: sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==}
@@ -7145,7 +7318,12 @@ packages:
resolution: {integrity: sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==}
dependencies:
mimic-response: 1.0.1
- dev: true
+
+ /clone@1.0.4:
+ resolution: {integrity: sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==}
+ engines: {node: '>=0.8'}
+ requiresBuild: true
+ dev: false
/clone@2.1.2:
resolution: {integrity: sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==}
@@ -7161,10 +7339,14 @@ packages:
resolution: {integrity: sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==}
engines: {iojs: '>= 1.0.0', node: '>= 0.12.0'}
+ /code-error-fragment@0.0.230:
+ resolution: {integrity: sha512-cadkfKp6932H8UkhzE/gcUqhRMNf8jHzkAN7+5Myabswaghu4xABTgPHDCjW+dBAJxj/SpkTYokpzDqY4pCzQw==}
+ engines: {node: '>= 4'}
+ dev: false
+
/code-point-at@1.1.0:
resolution: {integrity: sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA==}
engines: {node: '>=0.10.0'}
- dev: true
/collection-visit@1.0.0:
resolution: {integrity: sha512-lNkKvzEeMBBjUGHZ+q6z9pSJla0KWAQPvtzhEV9+iGyQYG+pBpl7xKDhxoNSOZH2hhv0v5k0y2yAM4o4SjoSkw==}
@@ -7210,6 +7392,10 @@ packages:
color-convert: 1.9.3
color-string: 1.9.1
+ /colorful@2.1.0:
+ resolution: {integrity: sha512-DpDLDvi/vPzqoPX7Dw44ZZf004DCdEcCx1pf5hq5aipVHXjwgRSYGCz3m17rA2XCduW91wJUapge8/3qLvjYcg==}
+ dev: false
+
/colors@1.0.3:
resolution: {integrity: sha512-pFGrxThWcWQ2MsAz6RtgeWe4NK2kUE1WfsrvvlctdII745EW9I0yflqhe7++M5LEc7bV2c/9/5zc8sFcpL0Drw==}
engines: {node: '>=0.1.90'}
@@ -7234,7 +7420,6 @@ packages:
/command-exists@1.2.9:
resolution: {integrity: sha512-LTQ/SGc+s0Xc0Fu5WaKnR0YiygZkm9eKFvyS+fRsU7/ZWFF8ykFM6Pc9aCVf1+xasOOZpO3BAVgVrKvsqKHV7w==}
- dev: true
/command-line-args@4.0.7:
resolution: {integrity: sha512-aUdPvQRAyBvQd2n7jXcsMDz68ckBJELXNzBybCHOibUWEg0mWTnaYCSRU8h9R+aNRSvDihJtssSRCiDRpLaezA==}
@@ -7268,10 +7453,18 @@ packages:
resolution: {integrity: sha512-Gar0ASD4BDyKC4hl4DwHqDrmvjoxWKZigVnAbn5H1owvm4CxCPdb0HQDehwNYMJpla5+M2tPmPARzhtYuwpHow==}
dev: true
+ /commander@5.1.0:
+ resolution: {integrity: sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==}
+ engines: {node: '>= 6'}
+ dev: false
+
/commander@8.3.0:
resolution: {integrity: sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==}
engines: {node: '>= 12'}
- dev: true
+
+ /compare-versions@4.1.4:
+ resolution: {integrity: sha512-FemMreK9xNyL8gQevsdRMrvO4lFCkQP7qbuktn1q8ndcNk1+0mz7lgE7b/sNvbhVgY4w6tMN1FDp6aADjqw2rw==}
+ dev: false
/component-emitter@1.3.1:
resolution: {integrity: sha512-T0+barUSQRTUQASh8bx02dl+DhF54GtIDY13Y3m9oWTklKbb3Wv974meRpeZ3lp1JpLVECWWNHC4vaG2XHXouQ==}
@@ -7291,6 +7484,35 @@ packages:
typedarray: 0.0.6
dev: true
+ /concurrently@6.5.1:
+ resolution: {integrity: sha512-FlSwNpGjWQfRwPLXvJ/OgysbBxPkWpiVjy1042b0U7on7S7qwwMIILRj7WTN1mTgqa582bG6NFuScOoh6Zgdag==}
+ engines: {node: '>=10.0.0'}
+ hasBin: true
+ dependencies:
+ chalk: 4.1.2
+ date-fns: 2.30.0
+ lodash: 4.17.21
+ rxjs: 6.6.7
+ spawn-command: 0.0.2
+ supports-color: 8.1.1
+ tree-kill: 1.2.2
+ yargs: 16.2.0
+ dev: false
+
+ /concurrently@9.1.2:
+ resolution: {integrity: sha512-H9MWcoPsYddwbOGM6difjVwVZHl63nwMEwDJG/L7VGtuaJhb12h2caPG2tVPWs7emuYix252iGfqOyrz1GczTQ==}
+ engines: {node: '>=18'}
+ hasBin: true
+ dependencies:
+ chalk: 4.1.2
+ lodash: 4.17.21
+ rxjs: 7.8.1
+ shell-quote: 1.8.2
+ supports-color: 8.1.1
+ tree-kill: 1.2.2
+ yargs: 17.7.2
+ dev: true
+
/condense-newlines@0.2.1:
resolution: {integrity: sha512-P7X+QL9Hb9B/c8HI5BFFKmjgBu2XpQuF98WZ9XkO+dBGgk5XgwiQz7o1SmpglNWId3581UcS0SFAWfoIhMHPfg==}
engines: {node: '>=0.10.0'}
@@ -7305,15 +7527,44 @@ packages:
ini: 1.3.8
proto-list: 1.2.4
+ /configstore@5.0.1:
+ resolution: {integrity: sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA==}
+ engines: {node: '>=8'}
+ dependencies:
+ dot-prop: 5.3.0
+ graceful-fs: 4.2.11
+ make-dir: 3.1.0
+ unique-string: 2.0.0
+ write-file-atomic: 3.0.3
+ xdg-basedir: 4.0.0
+ dev: false
+
/confusing-browser-globals@1.0.11:
resolution: {integrity: sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==}
dev: true
+ /consola@2.15.3:
+ resolution: {integrity: sha512-9vAdYbHj6x2fLKC4+oPH0kFzY/orMZyG2Aj+kNylHxKGJ/Ed4dpNyAQYwJOdqO4zdM7XpVHmyejQDcQHrnuXbw==}
+ dev: false
+
+ /console-browserify@1.1.0:
+ resolution: {integrity: sha512-duS7VP5pvfsNLDvL1O4VOEbw37AI3A4ZUQYemvDlnpGrNu9tprR7BYWpDYwC0Xia0Zxz5ZupdiIrUp0GH1aXfg==}
+ dependencies:
+ date-now: 0.1.4
+ dev: false
+
/console-control-strings@1.1.0:
resolution: {integrity: sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==}
requiresBuild: true
optional: true
+ /console.table@0.10.0:
+ resolution: {integrity: sha512-dPyZofqggxuvSf7WXvNjuRfnsOk1YazkVP8FdxH4tcH2c37wc79/Yl6Bhr7Lsu00KMgy2ql/qCMuNu8xctZM8g==}
+ engines: {node: '> 0.10'}
+ dependencies:
+ easy-table: 1.1.0
+ dev: false
+
/consolidate@0.16.0(ejs@3.1.10):
resolution: {integrity: sha512-Nhl1wzCslqXYTJVDyJCu3ODohy9OfBMB5uD2BiBTzd7w+QY0lBzafkR8y8755yMYHAaMD4NuzbAw03/xzfw+eQ==}
engines: {node: '>= 0.10.0'}
@@ -7519,7 +7770,6 @@ packages:
/cookie@0.4.2:
resolution: {integrity: sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==}
engines: {node: '>= 0.6'}
- dev: true
/cookie@0.6.0:
resolution: {integrity: sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==}
@@ -7529,7 +7779,6 @@ packages:
/cookie@0.7.1:
resolution: {integrity: sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==}
engines: {node: '>= 0.6'}
- dev: true
/cookiejar@2.1.4:
resolution: {integrity: sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw==}
@@ -7572,9 +7821,13 @@ packages:
requiresBuild: true
dev: true
+ /core-js@3.40.0:
+ resolution: {integrity: sha512-7vsMc/Lty6AGnn7uFpYT56QesI5D2Y/UkgKounk87OP9Z2H9Z8kj6jzcSGAxFmUtDOS0ntK6lbQz+Nsa0Jj6mQ==}
+ requiresBuild: true
+ dev: false
+
/core-util-is@1.0.2:
resolution: {integrity: sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==}
- dev: true
/core-util-is@1.0.3:
resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==}
@@ -7739,7 +7992,6 @@ packages:
semver: 5.7.2
shebang-command: 1.2.0
which: 1.3.1
- dev: true
/cross-spawn@7.0.3:
resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==}
@@ -7748,6 +8000,7 @@ packages:
path-key: 3.1.1
shebang-command: 2.0.0
which: 2.0.2
+ dev: true
/cross-spawn@7.0.6:
resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==}
@@ -7756,7 +8009,6 @@ packages:
path-key: 3.1.1
shebang-command: 2.0.0
which: 2.0.2
- dev: true
/crypt@0.0.2:
resolution: {integrity: sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow==}
@@ -7796,6 +8048,11 @@ packages:
/crypto-js@4.2.0:
resolution: {integrity: sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==}
+ /crypto-random-string@2.0.0:
+ resolution: {integrity: sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==}
+ engines: {node: '>=8'}
+ dev: false
+
/css-select@5.1.0:
resolution: {integrity: sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==}
dependencies:
@@ -7824,7 +8081,11 @@ packages:
engines: {node: '>=0.10'}
dependencies:
assert-plus: 1.0.0
- dev: true
+
+ /data-uri-to-buffer@6.0.2:
+ resolution: {integrity: sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw==}
+ engines: {node: '>= 14'}
+ dev: false
/data-view-buffer@1.0.1:
resolution: {integrity: sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==}
@@ -7880,6 +8141,17 @@ packages:
is-data-view: 1.0.2
dev: true
+ /date-fns@2.30.0:
+ resolution: {integrity: sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==}
+ engines: {node: '>=0.11'}
+ dependencies:
+ '@babel/runtime': 7.26.0
+ dev: false
+
+ /date-now@0.1.4:
+ resolution: {integrity: sha512-AsElvov3LoNB7tf5k37H2jYSB+ZZPMT5sG2QjJCcdlV5chIv6htBUBUui2IKRjgtKAKtCBN7Zbwa+MtwLjSeNw==}
+ dev: false
+
/death@1.1.0:
resolution: {integrity: sha512-vsV6S4KVHvTGxbEcij7hkWRv0It+sGGWVOM67dQde/o5Xjnr+KmLjxWJii2uEObIrt1CcM9w0Yaovx+iOlIL+w==}
dev: true
@@ -7951,6 +8223,19 @@ packages:
dependencies:
ms: 2.1.2
+ /debug@4.4.0(supports-color@5.5.0):
+ resolution: {integrity: sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==}
+ engines: {node: '>=6.0'}
+ peerDependencies:
+ supports-color: '*'
+ peerDependenciesMeta:
+ supports-color:
+ optional: true
+ dependencies:
+ ms: 2.1.3
+ supports-color: 5.5.0
+ dev: true
+
/debug@4.4.0(supports-color@8.1.1):
resolution: {integrity: sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==}
engines: {node: '>=6.0'}
@@ -7966,12 +8251,10 @@ packages:
/decamelize@1.2.0:
resolution: {integrity: sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==}
engines: {node: '>=0.10.0'}
- dev: true
/decamelize@4.0.0:
resolution: {integrity: sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==}
engines: {node: '>=10'}
- dev: true
/decimal.js@10.5.0:
resolution: {integrity: sha512-8vDa8Qxvr/+d94hSh5P3IJwI5t8/c0KsMp+g8bNw9cY2icONa5aPfvKeieW1WlG0WQYwwhJ7mjui2xtiePQSXw==}
@@ -7986,7 +8269,6 @@ packages:
engines: {node: '>=4'}
dependencies:
mimic-response: 1.0.1
- dev: true
/decompress-response@4.2.1:
resolution: {integrity: sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw==}
@@ -8034,9 +8316,15 @@ packages:
resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==}
dev: true
+ /defaults@1.0.4:
+ resolution: {integrity: sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==}
+ requiresBuild: true
+ dependencies:
+ clone: 1.0.4
+ dev: false
+
/defer-to-connect@1.1.3:
resolution: {integrity: sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==}
- dev: true
/defer-to-connect@2.0.1:
resolution: {integrity: sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==}
@@ -8101,6 +8389,15 @@ packages:
requiresBuild: true
dev: true
+ /degenerator@5.0.1:
+ resolution: {integrity: sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==}
+ engines: {node: '>= 14'}
+ dependencies:
+ ast-types: 0.13.4
+ escodegen: 2.1.0
+ esprima: 4.0.1
+ dev: false
+
/delay@5.0.0:
resolution: {integrity: sha512-ReEBKkIfe4ya47wlPYf/gu5ib6yUG0/Aez0JQZQz94kiWtRQvZIQbTiehsnwHvLSWJnQdhVeqYue7Id1dKr0qw==}
engines: {node: '>=10'}
@@ -8186,7 +8483,6 @@ packages:
/diff@5.2.0:
resolution: {integrity: sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==}
engines: {node: '>=0.3.1'}
- dev: true
/diffie-hellman@5.0.3:
resolution: {integrity: sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==}
@@ -8246,6 +8542,13 @@ packages:
esutils: 2.0.3
dev: true
+ /dom-serializer@0.2.2:
+ resolution: {integrity: sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==}
+ dependencies:
+ domelementtype: 2.3.0
+ entities: 2.2.0
+ dev: false
+
/dom-serializer@2.0.0:
resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==}
dependencies:
@@ -8259,9 +8562,18 @@ packages:
requiresBuild: true
dev: true
+ /domelementtype@1.3.1:
+ resolution: {integrity: sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==}
+ dev: false
+
/domelementtype@2.3.0:
resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==}
- dev: true
+
+ /domhandler@2.3.0:
+ resolution: {integrity: sha512-q9bUwjfp7Eif8jWxxxPSykdRZAb6GkguBGSgvvCrhI9wB71W2K/Kvv4E61CF/mcCfnVJDeDWx/Vb/uAqbDj6UQ==}
+ dependencies:
+ domelementtype: 1.3.1
+ dev: false
/domhandler@5.0.3:
resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==}
@@ -8270,6 +8582,13 @@ packages:
domelementtype: 2.3.0
dev: true
+ /domutils@1.5.1:
+ resolution: {integrity: sha512-gSu5Oi/I+3wDENBsOWBiRK1eoGxcywYSqg3rR960/+EfY0CF4EX1VPkgHOZ3WiS/Jg2DtliF6BhWcHlfpYUcGw==}
+ dependencies:
+ dom-serializer: 0.2.2
+ domelementtype: 1.3.1
+ dev: false
+
/domutils@3.2.2:
resolution: {integrity: sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==}
dependencies:
@@ -8290,10 +8609,16 @@ packages:
no-case: 3.0.4
tslib: 2.6.3
+ /dot-prop@5.3.0:
+ resolution: {integrity: sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==}
+ engines: {node: '>=8'}
+ dependencies:
+ is-obj: 2.0.0
+ dev: false
+
/dotenv@8.6.0:
resolution: {integrity: sha512-IrPdXQsk2BbzvCBGBOTmmSH5SodmqZNt4ERAZDmW4CT+tL8VtvinqywuANaFu4bOMWki16nqf0e4oC0QIaDr/g==}
engines: {node: '>=10'}
- dev: true
/dotignore@0.1.2:
resolution: {integrity: sha512-UGGGWfSauusaVJC+8fgV+NVvBXkCTmVv7sk6nojDZZvuOUNGUy0Zk4UpHQD6EDjS0jpBwcACvH4eofvyzBcRDw==}
@@ -8325,21 +8650,24 @@ packages:
call-bind-apply-helpers: 1.0.1
es-errors: 1.3.0
gopd: 1.2.0
- dev: true
/duplexer3@0.1.5:
resolution: {integrity: sha512-1A8za6ws41LQgv9HrE/66jyC5yuSjQ3L/KOpFtoBilsAK2iA2wuS5rTt1OCzIvtS2V7nVmedsUU+DGRcjBmOYA==}
- dev: true
/eastasianwidth@0.2.0:
resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==}
+ /easy-table@1.1.0:
+ resolution: {integrity: sha512-oq33hWOSSnl2Hoh00tZWaIPi1ievrD9aFG82/IgjlycAnW9hHx5PkJiXpxPsgEE+H7BsbVQXFVFST8TEXS6/pA==}
+ optionalDependencies:
+ wcwidth: 1.0.1
+ dev: false
+
/ecc-jsbn@0.1.2:
resolution: {integrity: sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==}
dependencies:
jsbn: 0.1.1
safer-buffer: 2.1.2
- dev: true
/eccrypto@1.1.6:
resolution: {integrity: sha512-d78ivVEzu7Tn0ZphUUaL43+jVPKTMPFGtmgtz1D0LrFn7cY3K8CdrvibuLz2AAkHBLKZtR8DMbB2ukRYFk987A==}
@@ -8361,7 +8689,7 @@ packages:
'@one-ini/wasm': 0.1.1
commander: 10.0.1
minimatch: 9.0.1
- semver: 7.6.2
+ semver: 7.6.3
/ee-first@1.1.1:
resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==}
@@ -8435,7 +8763,6 @@ packages:
/encodeurl@2.0.0:
resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==}
engines: {node: '>= 0.8'}
- dev: true
/encoding-down@5.0.4:
resolution: {integrity: sha512-8CIZLDcSKxgzT+zX8ZVfgNbu8Md2wq/iqa1Y7zyVR18QBEAc0Nmzuvj/N5ykSKpfGzjM8qxbaFntLPwnVoUhZw==}
@@ -8480,7 +8807,14 @@ packages:
dependencies:
ansi-colors: 4.1.3
strip-ansi: 6.0.1
- dev: true
+
+ /entities@1.0.0:
+ resolution: {integrity: sha512-LbLqfXgJMmy81t+7c14mnulFHJ170cM6E+0vMXR9k/ZiZwgX8i5pNgjTCX3SO4VeUsFLV+8InixoretwU+MjBQ==}
+ dev: false
+
+ /entities@2.2.0:
+ resolution: {integrity: sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==}
+ dev: false
/entities@4.5.0:
resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==}
@@ -8645,7 +8979,6 @@ packages:
/es-define-property@1.0.1:
resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==}
engines: {node: '>= 0.4'}
- dev: true
/es-errors@1.3.0:
resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==}
@@ -8663,7 +8996,6 @@ packages:
engines: {node: '>= 0.4'}
dependencies:
es-errors: 1.3.0
- dev: true
/es-set-tostringtag@2.0.3:
resolution: {integrity: sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==}
@@ -8727,6 +9059,10 @@ packages:
es6-symbol: 3.1.4
dev: true
+ /es6-promise@3.3.1:
+ resolution: {integrity: sha512-SOp9Phqvqn7jtEUxPWdWfWoLmyt2VaJ6MpvP9Comy1MceMXqE6bxvaTu4iaxpYYPzhny28Lc+M87/c2cPK6lDg==}
+ dev: false
+
/es6-promise@4.2.8:
resolution: {integrity: sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==}
@@ -8779,6 +9115,11 @@ packages:
resolution: {integrity: sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==}
engines: {node: '>=6'}
+ /escape-goat@2.1.1:
+ resolution: {integrity: sha512-8/uIhbG12Csjy2JEW7D9pHbreaVaS/OpN3ycnyvElTdwM5n6GY6W6e2IPemfvGZeUMqZ9A/3GqIZMgKnBhAw/Q==}
+ engines: {node: '>=8'}
+ dev: false
+
/escape-html@1.0.3:
resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==}
@@ -8789,7 +9130,6 @@ packages:
/escape-string-regexp@4.0.0:
resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==}
engines: {node: '>=10'}
- dev: true
/escodegen@1.7.1:
resolution: {integrity: sha512-2cd7+JUtUEmZVpGmfF9r+uRYXswJAkf85Ce8GvdBa7hSvdjY8hGo+rwC5syAgYzqHpfxNJzLntFjw6879yPbgQ==}
@@ -8817,6 +9157,18 @@ packages:
source-map: 0.2.0
dev: true
+ /escodegen@2.1.0:
+ resolution: {integrity: sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==}
+ engines: {node: '>=6.0'}
+ hasBin: true
+ dependencies:
+ esprima: 4.0.1
+ estraverse: 5.3.0
+ esutils: 2.0.3
+ optionalDependencies:
+ source-map: 0.6.1
+ dev: false
+
/eslint-config-airbnb-base@15.0.0(eslint-plugin-import@2.31.0)(eslint@8.57.1):
resolution: {integrity: sha512-xaX3z4ZZIcFLvh2oUNvcX5oEofXda7giYmuplVxoOg5A7EXJMrUyqRgR+mhDhPK8LZ4PttFOBvCYDbX3sUoUig==}
engines: {node: ^10.12.0 || >=12.0.0}
@@ -9270,7 +9622,6 @@ packages:
resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==}
engines: {node: '>=4'}
hasBin: true
- dev: true
/esquery@1.6.0:
resolution: {integrity: sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==}
@@ -9299,12 +9650,10 @@ packages:
/estraverse@5.3.0:
resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==}
engines: {node: '>=4.0'}
- dev: true
/esutils@2.0.3:
resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==}
engines: {node: '>=0.10.0'}
- dev: true
/etag@1.8.1:
resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==}
@@ -9477,7 +9826,7 @@ packages:
resolution: {integrity: sha512-NtlDnaVZah146Rm8HMRUNMgIwG/ED4jiqk0TME9zFheMl1jOp6jL1m0NKGjJwehXQ6ZKCPr16MTr+qspKpEXNg==}
requiresBuild: true
dependencies:
- async: 2.6.2
+ async: 2.6.4
clone: 2.1.2
concat-stream: 1.6.2
end-of-stream: 1.4.4
@@ -9493,7 +9842,7 @@ packages:
resolution: {integrity: sha512-/MSbf/r2/Ld8o0l15AymjOTlPqpN8Cr4ByUEA9GtR4x0yAh3TdtDzEg29zMjXCNPI7u6E5fOQdj/Cf9Tc7oVNw==}
deprecated: 'New package name format for new versions: @ethereumjs/ethash. Please update.'
dependencies:
- async: 2.6.2
+ async: 2.6.4
buffer-xor: 2.0.2
ethereumjs-util: 7.1.5
miller-rabin: 4.0.1
@@ -9546,7 +9895,6 @@ packages:
'@noble/secp256k1': 1.7.1
'@scure/bip32': 1.1.5
'@scure/bip39': 1.1.1
- dev: true
/ethereum-cryptography@2.2.1:
resolution: {integrity: sha512-r/W8lkHSiTLxUxW8Rf3u4HGB0xQweG2RyETjywylKZSzLWoWAijRz8WCuOtJ6wah+avllXBqZuk29HCCvhEIRg==}
@@ -9592,6 +9940,7 @@ packages:
/ethereumjs-abi@0.6.5:
resolution: {integrity: sha512-rCjJZ/AE96c/AAZc6O3kaog4FhOsAViaysBxqJNy2+LHP0ttH0zkZ7nXdVHOAyt6lFwLO0nlCwWszysG/ao1+g==}
+ deprecated: This library has been deprecated and usage is discouraged.
dependencies:
bn.js: 4.12.1
ethereumjs-util: 4.5.1
@@ -9649,7 +9998,7 @@ packages:
resolution: {integrity: sha512-zCxaRMUOzzjvX78DTGiKjA+4h2/sF0OYL1QuPux0DHpyq8XiNoF5GYHtb++GUxVlMsMfZV7AVyzbtgcRdIcEPQ==}
deprecated: 'New package name format for new versions: @ethereumjs/blockchain. Please update.'
dependencies:
- async: 2.6.2
+ async: 2.6.4
ethashjs: 0.0.8
ethereumjs-block: 2.2.2
ethereumjs-common: 1.5.2
@@ -9795,6 +10144,14 @@ packages:
ethers: 4.0.49
dev: false
+ /ethers-types@3.18.1(ethers@5.7.2):
+ resolution: {integrity: sha512-VUHisDlJrg871DxneLe5PJt8Jyg5radEoriym7KDYiwf8ZeXZh8mIGWtQnRMO4exfj2Qu2nX0xjzgyoKHIwkQg==}
+ peerDependencies:
+ ethers: ^6.0.0
+ dependencies:
+ ethers: 5.7.2
+ dev: false
+
/ethers@4.0.49:
resolution: {integrity: sha512-kPltTvWiyu+OktYy1IStSO16i2e7cS9D9OxZ81q2UUaiNPVrm/RTcbxamCXF9VUSKzJIdJV68EAIhTEVBalRWg==}
dependencies:
@@ -9940,7 +10297,11 @@ packages:
p-finally: 1.0.0
signal-exit: 3.0.7
strip-eof: 1.0.0
- dev: true
+
+ /exit@0.1.2:
+ resolution: {integrity: sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==}
+ engines: {node: '>= 0.8.0'}
+ dev: false
/expand-brackets@0.1.5:
resolution: {integrity: sha512-hxx03P2dJxss6ceIeri9cmYOT4SRs3Zk3afZwWpOsRqLqprhTR8u++SlC+sFGsQr7WGFPdMF7Gjc1njDLDK6UA==}
@@ -10010,7 +10371,7 @@ packages:
transitivePeerDependencies:
- bufferutil
- utf-8-validate
- dev: true
+ dev: false
/express@4.19.2:
resolution: {integrity: sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==}
@@ -10088,7 +10449,6 @@ packages:
vary: 1.1.2
transitivePeerDependencies:
- supports-color
- dev: true
/ext@1.7.0:
resolution: {integrity: sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==}
@@ -10112,7 +10472,15 @@ packages:
/extend@3.0.2:
resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==}
- dev: true
+
+ /external-editor@3.1.0:
+ resolution: {integrity: sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==}
+ engines: {node: '>=4'}
+ dependencies:
+ chardet: 0.7.0
+ iconv-lite: 0.4.24
+ tmp: 0.0.33
+ dev: false
/extglob@0.3.2:
resolution: {integrity: sha512-1FOj1LOwn42TMrruOHGt18HemVnbwAmAak7krWk+wa93KXxGbK+2jpezm+ytJYDaBX0/SPLZFHKM7m+tKobWGg==}
@@ -10140,7 +10508,6 @@ packages:
/extsprintf@1.3.0:
resolution: {integrity: sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==}
engines: {'0': node >=0.6.0}
- dev: true
/eyes@0.1.8:
resolution: {integrity: sha512-GipyPsXO1anza0AOZdy69Im7hGFCNB7Y/NGjDlZGJ3GJJLtwNSb2vrzYrTYJRrRloVx7pl+bhUaTB8yiccPvFQ==}
@@ -10162,11 +10529,9 @@ packages:
/fast-deep-equal@1.1.0:
resolution: {integrity: sha512-fueX787WZKCV0Is4/T2cyAdM4+x1S3MXXOAhavE1ys/W42SHAPacLTQhucja22QBYrfGw50M2sRiXPtTGv9Ymw==}
- dev: true
/fast-deep-equal@3.1.3:
resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==}
- dev: true
/fast-diff@1.3.0:
resolution: {integrity: sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==}
@@ -10196,7 +10561,6 @@ packages:
/fast-json-stable-stringify@2.1.0:
resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==}
- dev: true
/fast-levenshtein@1.0.7:
resolution: {integrity: sha512-hYsfI0s4lfQ2rHVFKXwAr/L/ZSbq9TZwgXtZqW7ANcn9o9GKvcbWxOnxx7jykXf/Ezv1V8TvaBEKcGK7DWKX5A==}
@@ -10206,13 +10570,13 @@ packages:
resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==}
dev: true
+ /fast-safe-stringify@2.1.1:
+ resolution: {integrity: sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==}
+ dev: false
+
/fast-stable-stringify@1.0.0:
resolution: {integrity: sha512-wpYMUmFu5f00Sm0cj2pfivpmawLZ0NKdviQ4w9zJeR8JVtOpOxHmLaJuj0vxvGqMJQWyP/COUkF75/57OKyRag==}
- /fast-uri@3.0.6:
- resolution: {integrity: sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==}
- dev: true
-
/fastestsmallesttextencoderdecoder@1.0.22:
resolution: {integrity: sha512-Pb8d48e+oIuY4MaM64Cd7OW1gt4nxCHs7/ddPPZ/Ic3sg8yVGM7O9wDvZ7us6ScaUupzM+pfBolwtYhN1IxBIw==}
@@ -10231,7 +10595,6 @@ packages:
optional: true
dependencies:
picomatch: 4.0.2
- dev: true
/fecha@4.2.3:
resolution: {integrity: sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw==}
@@ -10243,6 +10606,13 @@ packages:
node-fetch: 1.7.3
dev: true
+ /figures@3.2.0:
+ resolution: {integrity: sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==}
+ engines: {node: '>=8'}
+ dependencies:
+ escape-string-regexp: 1.0.5
+ dev: false
+
/file-entry-cache@6.0.1:
resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==}
engines: {node: ^10.12.0 || >=12.0.0}
@@ -10296,7 +10666,6 @@ packages:
engines: {node: '>=8'}
dependencies:
to-regex-range: 5.0.1
- dev: true
/finalhandler@1.2.0:
resolution: {integrity: sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==}
@@ -10326,7 +10695,6 @@ packages:
unpipe: 1.0.0
transitivePeerDependencies:
- supports-color
- dev: true
/find-in-files@0.5.0:
resolution: {integrity: sha512-VraTc6HdtdSHmAp0yJpAy20yPttGKzyBWc7b7FPnnsX9TOgmKx0g9xajizpF/iuu4IvNK4TP0SpyBT9zAlwG+g==}
@@ -10358,13 +10726,19 @@ packages:
locate-path: 2.0.0
dev: true
+ /find-up@3.0.0:
+ resolution: {integrity: sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==}
+ engines: {node: '>=6'}
+ dependencies:
+ locate-path: 3.0.0
+ dev: false
+
/find-up@5.0.0:
resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==}
engines: {node: '>=10'}
dependencies:
locate-path: 6.0.0
path-exists: 4.0.0
- dev: true
/find-yarn-workspace-root@1.2.1:
resolution: {integrity: sha512-dVtfb0WuQG+8Ag2uWkbG79hOUzEsRrhBzgfn86g2sJPkzmcpGdghbNTfUKGTxymFrY/tLIodDzLoW9nOJ4FY8Q==}
@@ -10399,7 +10773,6 @@ packages:
/flat@5.0.2:
resolution: {integrity: sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==}
hasBin: true
- dev: true
/flatted@3.3.1:
resolution: {integrity: sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==}
@@ -10428,9 +10801,10 @@ packages:
optional: true
dependencies:
debug: 4.3.5
+ dev: true
- /follow-redirects@1.15.9(debug@4.4.0):
- resolution: {integrity: sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==}
+ /follow-redirects@1.15.6(debug@4.4.0):
+ resolution: {integrity: sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==}
engines: {node: '>=4.0'}
peerDependencies:
debug: '*'
@@ -10440,6 +10814,15 @@ packages:
dependencies:
debug: 4.4.0(supports-color@8.1.1)
+ /follow-redirects@1.15.9:
+ resolution: {integrity: sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==}
+ engines: {node: '>=4.0'}
+ peerDependencies:
+ debug: '*'
+ peerDependenciesMeta:
+ debug:
+ optional: true
+
/for-each@0.3.3:
resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==}
dependencies:
@@ -10462,12 +10845,11 @@ packages:
resolution: {integrity: sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==}
engines: {node: '>=14'}
dependencies:
- cross-spawn: 7.0.3
+ cross-spawn: 7.0.6
signal-exit: 4.1.0
/forever-agent@0.6.1:
resolution: {integrity: sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==}
- dev: true
/form-data-encoder@1.7.1:
resolution: {integrity: sha512-EFRDrsMm/kyqbTQocNvRXMLjc7Es2Vk+IQFx/YW7hkUH1eBl4J1fqiP34l74Yt0pFLCNpc06fkbVk00008mzjg==}
@@ -10480,7 +10862,6 @@ packages:
asynckit: 0.4.0
combined-stream: 1.0.8
mime-types: 2.1.35
- dev: true
/form-data@2.5.2:
resolution: {integrity: sha512-GgwY0PS7DbXqajuGf4OYlsrIu3zgxD6Vvql43IBhm6MahqA5SK/7mwhtNj2AdH2z35YR34ujJ7BN+3fFC3jP5Q==}
@@ -10490,7 +10871,6 @@ packages:
combined-stream: 1.0.8
mime-types: 2.1.35
safe-buffer: 5.2.1
- dev: true
/form-data@4.0.0:
resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==}
@@ -10514,7 +10894,6 @@ packages:
/fp-ts@1.19.3:
resolution: {integrity: sha512-H5KQDspykdHuztLTg+ajGN0Z2qUjcEf3Ybxc6hLt0k7/zPkn29XnKnxlBPyW2XIddWrGaJBzBl4VLYOtk39yZg==}
- dev: true
/fragment-cache@0.2.1:
resolution: {integrity: sha512-GMBAbW9antB8iZRHLoGw0b3HANt57diZYFO/HL1JGIC1MjKrdmhxvrJbupnVvpys0zsz7yBApXdQyfepKly2kA==}
@@ -10547,7 +10926,6 @@ packages:
graceful-fs: 4.2.11
jsonfile: 6.1.0
universalify: 2.0.1
- dev: true
/fs-extra@4.0.3:
resolution: {integrity: sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==}
@@ -10564,7 +10942,6 @@ packages:
graceful-fs: 4.2.11
jsonfile: 4.0.0
universalify: 0.1.2
- dev: true
/fs-extra@8.1.0:
resolution: {integrity: sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==}
@@ -10763,7 +11140,6 @@ packages:
/get-caller-file@1.0.3:
resolution: {integrity: sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==}
- dev: true
/get-caller-file@2.0.5:
resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==}
@@ -10797,7 +11173,6 @@ packages:
has-symbols: 1.1.0
hasown: 2.0.2
math-intrinsics: 1.1.0
- dev: true
/get-paths@0.0.7:
resolution: {integrity: sha512-0wdJt7C1XKQxuCgouqd+ZvLJ56FQixKoki9MrFaO4EriqzXOiH9gbukaDE1ou08S8Ns3/yDzoBAISNPqj6e6tA==}
@@ -10816,7 +11191,6 @@ packages:
dependencies:
dunder-proto: 1.0.1
es-object-atoms: 1.1.1
- dev: true
/get-stdin@6.0.0:
resolution: {integrity: sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g==}
@@ -10833,14 +11207,12 @@ packages:
engines: {node: '>=6'}
dependencies:
pump: 3.0.2
- dev: true
/get-stream@5.2.0:
resolution: {integrity: sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==}
engines: {node: '>=8'}
dependencies:
pump: 3.0.2
- dev: true
/get-stream@6.0.1:
resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==}
@@ -10871,6 +11243,17 @@ packages:
resolve-pkg-maps: 1.0.0
dev: true
+ /get-uri@6.0.4:
+ resolution: {integrity: sha512-E1b1lFFLvLgak2whF2xDBcOy6NLVGZBqqjJjsIhvopKfWWEi64pLVTWWehV8KlLerZkfNTA95sTe2OdJKm1OzQ==}
+ engines: {node: '>= 14'}
+ dependencies:
+ basic-ftp: 5.0.5
+ data-uri-to-buffer: 6.0.2
+ debug: 4.4.0(supports-color@8.1.1)
+ transitivePeerDependencies:
+ - supports-color
+ dev: false
+
/get-value@2.0.6:
resolution: {integrity: sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA==}
engines: {node: '>=0.10.0'}
@@ -10880,7 +11263,6 @@ packages:
resolution: {integrity: sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==}
dependencies:
assert-plus: 1.0.0
- dev: true
/ghost-testrpc@0.0.2:
resolution: {integrity: sha512-i08dAEgJ2g8z5buJIrCTduwPIhih3DP+hOCTyyryikfV8T0bNvHnGXO67i0DD1H4GBDETTclPy9njZbfluQYrQ==}
@@ -10912,7 +11294,6 @@ packages:
engines: {node: '>= 6'}
dependencies:
is-glob: 4.0.3
- dev: true
/glob-parent@6.0.2:
resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==}
@@ -10950,7 +11331,7 @@ packages:
fs.realpath: 1.0.0
inflight: 1.0.6
inherits: 2.0.4
- minimatch: 3.0.4
+ minimatch: 3.1.2
once: 1.4.0
path-is-absolute: 1.0.1
dev: true
@@ -10990,6 +11371,23 @@ packages:
minimatch: 5.1.6
once: 1.4.0
+ /glob@9.3.5:
+ resolution: {integrity: sha512-e1LleDykUz2Iu+MTYdkSsuWX8lvAjAcs0Xef0lNIu0S2wOAzuTxCJtcd9S3cijlwYF18EsU3rzb8jPVobxDh9Q==}
+ engines: {node: '>=16 || 14 >=14.17'}
+ dependencies:
+ fs.realpath: 1.0.0
+ minimatch: 8.0.4
+ minipass: 4.2.8
+ path-scurry: 1.11.1
+ dev: false
+
+ /global-dirs@2.1.0:
+ resolution: {integrity: sha512-MG6kdOUh/xBnyo9cJFeIKkLEc1AyFq42QTU4XiX51i2NEdxLxLWXIjEjmqKeSuKR7pAZjTqUVoT2b2huxVLgYQ==}
+ engines: {node: '>=8'}
+ dependencies:
+ ini: 1.3.7
+ dev: false
+
/global-modules@2.0.0:
resolution: {integrity: sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==}
engines: {node: '>=6'}
@@ -11074,7 +11472,6 @@ packages:
/gopd@1.2.0:
resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==}
engines: {node: '>= 0.4'}
- dev: true
/got@11.8.6:
resolution: {integrity: sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g==}
@@ -11129,12 +11526,15 @@ packages:
p-cancelable: 1.1.0
to-readable-stream: 1.0.0
url-parse-lax: 3.0.0
- dev: true
/graceful-fs@4.2.11:
resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==}
requiresBuild: true
+ /grapheme-splitter@1.0.4:
+ resolution: {integrity: sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==}
+ dev: false
+
/graphemer@1.4.0:
resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==}
dev: true
@@ -11147,7 +11547,7 @@ packages:
graphql: ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0
dependencies:
graphql: 16.10.0
- tslib: 2.6.3
+ tslib: 2.8.1
optional: true
/graphql@16.10.0:
@@ -11182,7 +11582,6 @@ packages:
/har-schema@2.0.0:
resolution: {integrity: sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==}
engines: {node: '>=4'}
- dev: true
/har-validator@5.1.5:
resolution: {integrity: sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==}
@@ -11191,7 +11590,6 @@ packages:
dependencies:
ajv: 6.12.6
har-schema: 2.0.0
- dev: true
/hardhat-contract-sizer@2.10.0(hardhat@2.22.18):
resolution: {integrity: sha512-QiinUgBD5MqJZJh1hl1jc9dNnpJg7eE/w4/4GEnrcmZJJTDbVFNe3+/3Ep24XqISSkYxRz36czcPHKHd/a0dwA==}
@@ -11327,7 +11725,6 @@ packages:
- c-kzg
- supports-color
- utf-8-validate
- dev: true
/hardhat@2.22.6(ts-node@9.1.1)(typescript@4.9.5):
resolution: {integrity: sha512-abFEnd9QACwEtSvZZGSmzvw7N3zhQN1cDKz5SLHAupfG24qTHofCjqvD5kT5Wwsq5XOL0ON1Mq5rr4v0XX5ciw==}
@@ -11451,7 +11848,6 @@ packages:
/has-symbols@1.1.0:
resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==}
engines: {node: '>= 0.4'}
- dev: true
/has-tostringtag@1.0.2:
resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==}
@@ -11495,6 +11891,11 @@ packages:
kind-of: 4.0.0
dev: true
+ /has-yarn@2.1.0:
+ resolution: {integrity: sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw==}
+ engines: {node: '>=8'}
+ dev: false
+
/has@1.0.4:
resolution: {integrity: sha512-qdSAmqLF6209RFj4VVItywPMbm3vWylknmB3nvNiUIs72xAimcM8nVYxYr7ncvZq5qzk9MKIZR8ijqD/1QuYjQ==}
engines: {node: '>= 0.4.0'}
@@ -11543,7 +11944,6 @@ packages:
/he@1.2.0:
resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==}
hasBin: true
- dev: true
/header-case@1.0.1:
resolution: {integrity: sha512-i0q9mkOeSuhXw6bGgiQCCBgY/jlZuV/7dZXyZ9c6LcBrqwvT8eT719E9uxE5LiZftdl+z81Ugbg/VvXV4OJOeQ==}
@@ -11598,6 +11998,16 @@ packages:
resolution: {integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==}
dev: true
+ /htmlparser2@3.8.3:
+ resolution: {integrity: sha512-hBxEg3CYXe+rPIua8ETe7tmG3XDn9B0edOE/e9wH2nLczxzgdu0m0aNHY+5wFZiviLWLdANPJTssa92dMcXQ5Q==}
+ dependencies:
+ domelementtype: 1.3.1
+ domhandler: 2.3.0
+ domutils: 1.5.1
+ entities: 1.0.0
+ readable-stream: 1.1.14
+ dev: false
+
/htmlparser2@9.1.0:
resolution: {integrity: sha512-5zfg6mHUoaer/97TxnGpxmbR7zJtPwIYFMZ/H5ucTlPZhKvtum05yiPK3Mgai3a0DyVxv7qYqoweaEd2nrYQzQ==}
dependencies:
@@ -11674,6 +12084,16 @@ packages:
dev: false
optional: true
+ /http-proxy-agent@7.0.2:
+ resolution: {integrity: sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==}
+ engines: {node: '>= 14'}
+ dependencies:
+ agent-base: 7.1.3
+ debug: 4.4.0(supports-color@8.1.1)
+ transitivePeerDependencies:
+ - supports-color
+ dev: false
+
/http-response-object@3.0.2:
resolution: {integrity: sha512-bqX0XTF6fnXSQcEJ2Iuyr75yVakyjIDCqroJQ/aHfSdlM743Cwqoi2nDYMzLGWUcuTWGWy8AAvOKXTfiv6q9RA==}
dependencies:
@@ -11687,13 +12107,16 @@ packages:
assert-plus: 1.0.0
jsprim: 1.4.2
sshpk: 1.18.0
- dev: true
/http-status-codes@2.3.0:
resolution: {integrity: sha512-RJ8XvFvpPM/Dmc5SV+dC4y5PCeOhT3x1Hq0NU3rjGeg5a/CqlhZ7uudknPwZFz4aeAXDcbAyaeP7GAo9lvngtA==}
requiresBuild: true
optional: true
+ /http2-client@1.3.5:
+ resolution: {integrity: sha512-EC2utToWl4RKfs5zd36Mxq7nzHHBuomZboI0yYL6Y0RmBgT7Sgkq4rQ0ezFTYoIsSs7Tm9SJe+o2FcAg6GBhGA==}
+ dev: false
+
/http2-wrapper@1.0.3:
resolution: {integrity: sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==}
engines: {node: '>=10.19.0'}
@@ -11720,6 +12143,16 @@ packages:
transitivePeerDependencies:
- supports-color
+ /https-proxy-agent@7.0.6:
+ resolution: {integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==}
+ engines: {node: '>= 14'}
+ dependencies:
+ agent-base: 7.1.3
+ debug: 4.4.0(supports-color@8.1.1)
+ transitivePeerDependencies:
+ - supports-color
+ dev: false
+
/humanize-ms@1.2.1:
resolution: {integrity: sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==}
requiresBuild: true
@@ -11761,6 +12194,10 @@ packages:
/ieee754@1.2.1:
resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==}
+ /ignore-by-default@1.0.1:
+ resolution: {integrity: sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==}
+ dev: true
+
/ignore@4.0.6:
resolution: {integrity: sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==}
engines: {node: '>= 4'}
@@ -11791,7 +12228,6 @@ packages:
/immutable@4.3.7:
resolution: {integrity: sha512-1hqclzwYwjRDFLjcFxOM5AYkkG0rpFPpr1RLPMEuGczoS7YA8gLhy8SWXYRAA/XwfEHpfo3cw5JGioS32fnMRw==}
- dev: true
/import-fresh@3.3.0:
resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==}
@@ -11801,6 +12237,11 @@ packages:
resolve-from: 4.0.0
dev: true
+ /import-lazy@2.1.0:
+ resolution: {integrity: sha512-m7ZEHgtw69qOGw+jwxXkHlrlIPdTGkyh66zXZ1ajZbxkDBNjSY/LGbmjc7h0s2ELsUDTAhFr55TrPSSqJGPG0A==}
+ engines: {node: '>=4'}
+ dev: false
+
/imul@1.0.1:
resolution: {integrity: sha512-WFAgfwPLAjU66EKt6vRdTlKj4nAgIDQzh29JonLa4Bqtl6D8JrIMvWjCnx7xEjVNmP3U0fM5o8ZObk7d0f62bA==}
engines: {node: '>=0.10.0'}
@@ -11836,9 +12277,34 @@ packages:
/inherits@2.0.4:
resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==}
+ /ini@1.3.7:
+ resolution: {integrity: sha512-iKpRpXP+CrP2jyrxvg1kMUpXDyRUFDWurxbnVT1vQPx+Wz9uCYsMIqYuSBLV+PAaZG/d7kRLKRFc9oDMsH+mFQ==}
+ dev: false
+
/ini@1.3.8:
resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==}
+ /inquirer@8.2.6:
+ resolution: {integrity: sha512-M1WuAmb7pn9zdFRtQYk26ZBoY043Sse0wVDdk4Bppr+JOXyQYybdtvK+l9wUibhtjdjvtoiNy8tk+EgsYIUqKg==}
+ engines: {node: '>=12.0.0'}
+ dependencies:
+ ansi-escapes: 4.3.2
+ chalk: 4.1.2
+ cli-cursor: 3.1.0
+ cli-width: 3.0.0
+ external-editor: 3.1.0
+ figures: 3.2.0
+ lodash: 4.17.21
+ mute-stream: 0.0.8
+ ora: 5.4.1
+ run-async: 2.4.1
+ rxjs: 7.8.1
+ string-width: 4.2.3
+ strip-ansi: 6.0.1
+ through: 2.3.8
+ wrap-ansi: 6.2.0
+ dev: false
+
/internal-slot@1.0.7:
resolution: {integrity: sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==}
engines: {node: '>= 0.4'}
@@ -11873,11 +12339,15 @@ packages:
engines: {node: '>=0.10.0'}
dev: true
+ /invert-kv@2.0.0:
+ resolution: {integrity: sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==}
+ engines: {node: '>=4'}
+ dev: false
+
/io-ts@1.10.4:
resolution: {integrity: sha512-b23PteSnYXSONJ6JQXRAlvJhuw8KOtkqa87W4wDtvMrud/DTJd5X+NpOOI+O/zZwVq6v0VLAaJ+1EDViKEuN9g==}
dependencies:
fp-ts: 1.19.3
- dev: true
/ioredis@5.4.1:
resolution: {integrity: sha512-2YZsvl7jopIa1gaePkeMtd9rAcSjOOjPtpcLlOeusyO+XH2SK5ZcT+UCrElPP+WVIInh2TzeI4XW9ENaSLVVHA==}
@@ -11921,7 +12391,6 @@ packages:
jsbn: 1.1.0
sprintf-js: 1.1.3
dev: false
- optional: true
/ipaddr.js@1.9.1:
resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==}
@@ -11945,6 +12414,7 @@ packages:
/is-arguments@1.2.0:
resolution: {integrity: sha512-7bVbi0huj/wrIAOzb8U1aszg9kdi3KN/CyU19CTI7tAoZYEZoL9yCDXpbXN+uPsuWnP02cyug1gleqq+TU+YCA==}
engines: {node: '>= 0.4'}
+ requiresBuild: true
dependencies:
call-bound: 1.0.3
has-tostringtag: 1.0.2
@@ -12010,7 +12480,6 @@ packages:
engines: {node: '>=8'}
dependencies:
binary-extensions: 2.3.0
- dev: true
/is-boolean-object@1.1.2:
resolution: {integrity: sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==}
@@ -12051,7 +12520,6 @@ packages:
hasBin: true
dependencies:
ci-info: 2.0.0
- dev: true
/is-core-module@2.14.0:
resolution: {integrity: sha512-a5dFJih5ZLYlRtDc0dZWP7RiKr6xIKzmn/oAYCDvdLThadVgyJwlaoQPmRtMSpz+rk0OGAgIu+TcM9HUF0fk1A==}
@@ -12157,7 +12625,6 @@ packages:
/is-extglob@2.1.1:
resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==}
engines: {node: '>=0.10.0'}
- dev: true
/is-finalizationregistry@1.1.1:
resolution: {integrity: sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==}
@@ -12183,12 +12650,10 @@ packages:
engines: {node: '>=0.10.0'}
dependencies:
number-is-nan: 1.0.1
- dev: true
/is-fullwidth-code-point@2.0.0:
resolution: {integrity: sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==}
engines: {node: '>=4'}
- dev: true
/is-fullwidth-code-point@3.0.0:
resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==}
@@ -12227,17 +12692,29 @@ packages:
engines: {node: '>=0.10.0'}
dependencies:
is-extglob: 2.1.1
- dev: true
/is-hex-prefixed@1.0.0:
resolution: {integrity: sha512-WvtOiug1VFrE9v1Cydwm+FnXd3+w9GaeVUss5W4v/SLy3UW00vP+6iNF2SdnfiBoLy4bTqVdkftNGTUeOFVsbA==}
engines: {node: '>=6.5.0', npm: '>=3'}
- /is-lambda@1.0.1:
- resolution: {integrity: sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==}
- requiresBuild: true
+ /is-installed-globally@0.3.2:
+ resolution: {integrity: sha512-wZ8x1js7Ia0kecP/CHM/3ABkAmujX7WPvQk6uu3Fly/Mk44pySulQpnHG46OMjHGXApINnV4QhY3SWnECO2z5g==}
+ engines: {node: '>=8'}
+ dependencies:
+ global-dirs: 2.1.0
+ is-path-inside: 3.0.3
dev: false
- optional: true
+
+ /is-interactive@1.0.0:
+ resolution: {integrity: sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==}
+ engines: {node: '>=8'}
+ dev: false
+
+ /is-lambda@1.0.1:
+ resolution: {integrity: sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==}
+ requiresBuild: true
+ dev: false
+ optional: true
/is-lower-case@1.1.3:
resolution: {integrity: sha512-+5A1e/WJpLLXZEDlgz4G//WYSHyQBD32qa4Jd3Lw06qQlv3fJHnp3YIHjTQSGzHMgzmVKz2ZP3rBxTHkPw/lxA==}
@@ -12255,6 +12732,11 @@ packages:
engines: {node: '>= 0.4'}
dev: true
+ /is-npm@4.0.0:
+ resolution: {integrity: sha512-96ECIfh9xtDDlPylNPXhzjsykHsMJZ18ASpaWzQyBr4YRTcVjUvzaHayDAES2oU/3KpljhHUjtSRNiDwi0F0ig==}
+ engines: {node: '>=8'}
+ dev: false
+
/is-number-object@1.0.7:
resolution: {integrity: sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==}
engines: {node: '>= 0.4'}
@@ -12292,17 +12774,19 @@ packages:
/is-number@7.0.0:
resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==}
engines: {node: '>=0.12.0'}
- dev: true
+
+ /is-obj@2.0.0:
+ resolution: {integrity: sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==}
+ engines: {node: '>=8'}
+ dev: false
/is-path-inside@3.0.3:
resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==}
engines: {node: '>=8'}
- dev: true
/is-plain-obj@2.1.0:
resolution: {integrity: sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==}
engines: {node: '>=8'}
- dev: true
/is-plain-object@2.0.4:
resolution: {integrity: sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==}
@@ -12361,7 +12845,6 @@ packages:
/is-stream@1.1.0:
resolution: {integrity: sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==}
engines: {node: '>=0.10.0'}
- dev: true
/is-stream@2.0.1:
resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==}
@@ -12414,12 +12897,10 @@ packages:
/is-typedarray@1.0.0:
resolution: {integrity: sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==}
- dev: true
/is-unicode-supported@0.1.0:
resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==}
engines: {node: '>=10'}
- dev: true
/is-upper-case@1.1.2:
resolution: {integrity: sha512-GQYSJMgfeAmVwh9ixyk888l7OIhNAGKtY6QA+IrWlu9MDTCaXmeozOZ2S9Knj7bQwBO/H6J2kb+pbyTUiMNbsw==}
@@ -12477,6 +12958,10 @@ packages:
is-docker: 2.2.1
dev: true
+ /is-yarn-global@0.3.0:
+ resolution: {integrity: sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw==}
+ dev: false
+
/isarray@0.0.1:
resolution: {integrity: sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==}
requiresBuild: true
@@ -12513,7 +12998,6 @@ packages:
/isstream@0.1.2:
resolution: {integrity: sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==}
- dev: true
/istanbul-combine@0.3.0:
resolution: {integrity: sha512-zWtpO29Qs2ruIRu6qYtsX5guqw+/JFcZlTLrv1XUoBHe30r9v8pJgisf4VbMK3P2gahZjP6SlY1cz4qZ2YHaxw==}
@@ -12573,6 +13057,11 @@ packages:
wordwrap: 1.0.0
dev: true
+ /iterare@1.2.1:
+ resolution: {integrity: sha512-RKYVTCjAnRthyJes037NX/IiqeidgN1xc3j1RjFfECFp28A1GVwK9nA+i0rJPaHqSZwygLzRnFlzUuHFoWWy+Q==}
+ engines: {node: '>=6'}
+ dev: false
+
/jackspeak@3.4.3:
resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==}
dependencies:
@@ -12688,17 +13177,14 @@ packages:
hasBin: true
dependencies:
argparse: 2.0.1
- dev: true
/jsbn@0.1.1:
resolution: {integrity: sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==}
- dev: true
/jsbn@1.1.0:
resolution: {integrity: sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==}
requiresBuild: true
dev: false
- optional: true
/jscrypto@1.0.3:
resolution: {integrity: sha512-lryZl0flhodv4SZHOqyb1bx5sKcJxj0VBo0Kzb4QMAg3L021IC9uGpl0RCZa+9KJwlRGSK2C80ITcwbe19OKLQ==}
@@ -12716,6 +13202,19 @@ packages:
requiresBuild: true
dev: true
+ /jshint@2.13.6:
+ resolution: {integrity: sha512-IVdB4G0NTTeQZrBoM8C5JFVLjV2KtZ9APgybDA1MK73xb09qFs0jCXyQLnCOp1cSZZZbvhq/6mfXHUTaDkffuQ==}
+ hasBin: true
+ dependencies:
+ cli: 1.0.1
+ console-browserify: 1.1.0
+ exit: 0.1.2
+ htmlparser2: 3.8.3
+ lodash: 4.17.21
+ minimatch: 3.0.4
+ strip-json-comments: 1.0.4
+ dev: false
+
/json-bigint@1.0.0:
resolution: {integrity: sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==}
dependencies:
@@ -12723,7 +13222,6 @@ packages:
/json-buffer@3.0.0:
resolution: {integrity: sha512-CuUqjv0FUZIdXkHPI8MezCnFCdaTAacej1TZYulLoAg1h/PhwkdXFN4V/gzY4g+fMBCOV2xF+rp7t2XD2ns/NQ==}
- dev: true
/json-buffer@3.0.1:
resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==}
@@ -12761,11 +13259,9 @@ packages:
/json-schema-traverse@0.3.1:
resolution: {integrity: sha512-4JD/Ivzg7PoW8NzdrBSr3UFwC9mHgvI7Z6z3QGBsSHgKaRTUDmyZAAKJo2UbG1kUVfS9WS8bi36N49U1xw43DA==}
- dev: true
/json-schema-traverse@0.4.1:
resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==}
- dev: true
/json-schema-traverse@1.0.0:
resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==}
@@ -12773,7 +13269,6 @@ packages:
/json-schema@0.4.0:
resolution: {integrity: sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==}
- dev: true
/json-stable-stringify-without-jsonify@1.0.1:
resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==}
@@ -12794,11 +13289,18 @@ packages:
/json-stream-stringify@3.1.6:
resolution: {integrity: sha512-x7fpwxOkbhFCaJDJ8vb1fBY3DdSa4AlITaz+HHILQJzdPMnHEFjxPwVUi1ALIbcIxDE0PNe/0i7frnY8QnBQog==}
engines: {node: '>=7.10.1'}
- dev: true
/json-stringify-safe@5.0.1:
resolution: {integrity: sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==}
+ /json-to-ast@2.1.0:
+ resolution: {integrity: sha512-W9Lq347r8tA1DfMvAGn9QNcgYm4Wm7Yc+k8e6vezpMnRT+NHbtlxgNBXRVjXe9YM6eTn6+p/MKOlV/aABJcSnQ==}
+ engines: {node: '>= 4'}
+ dependencies:
+ code-error-fragment: 0.0.230
+ grapheme-splitter: 1.0.4
+ dev: false
+
/json5@0.5.1:
resolution: {integrity: sha512-4xrs1aW+6N5DalkqSVA8fxh458CXvR99WU8WLKmq4v8eWAL86Xo3BVqyd3SkA9wEVjCMqyvvRRkshAdOnBp5rw==}
hasBin: true
@@ -12828,7 +13330,6 @@ packages:
resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==}
optionalDependencies:
graceful-fs: 4.2.11
- dev: true
/jsonfile@6.1.0:
resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==}
@@ -12846,6 +13347,11 @@ packages:
resolution: {integrity: sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==}
engines: {'0': node >= 0.2.0}
+ /jsonpointer@4.1.0:
+ resolution: {integrity: sha512-CXcRvMyTlnR53xMcKnuMzfCA5i/nfblTnnr74CZb6C4vG39eu6w51t7nKmU5MfLfbTgGItliNyjO/ciNPDqClg==}
+ engines: {node: '>=0.10.0'}
+ dev: false
+
/jsonschema@1.4.1:
resolution: {integrity: sha512-S6cATIPVv1z0IlxdN+zUk5EPjkGCdnhN4wVSBlvoUO1tOLJootbo9CquNJmbIh4yikWHiUedhRYrNPn1arpEmQ==}
dev: true
@@ -12861,7 +13367,6 @@ packages:
extsprintf: 1.3.0
json-schema: 0.4.0
verror: 1.10.0
- dev: true
/keccak256@1.0.6:
resolution: {integrity: sha512-8GLiM01PkdJVGUhR1e6M/AvWnSqYS0HaERI+K/QtStGDGlSTx2B1zTqZk4Zlqu5TxHJNTxWAdP9Y+WI50OApUw==}
@@ -12891,7 +13396,6 @@ packages:
resolution: {integrity: sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==}
dependencies:
json-buffer: 3.0.0
- dev: true
/keyv@4.5.4:
resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==}
@@ -12943,7 +13447,7 @@ packages:
resolution: {integrity: sha512-rm71jaA/P+6HeCpoRhmCv8KVBIi0tfGuO/dMKicbQnQW/YJntJ6MnnspkodoA4QstMVEZArsCphmd0bJEtoMjQ==}
engines: {node: '>= 7.6.0'}
dependencies:
- debug: 4.3.5
+ debug: 4.4.0(supports-color@8.1.1)
koa-compose: 4.1.0
transitivePeerDependencies:
- supports-color
@@ -12953,7 +13457,7 @@ packages:
engines: {node: '>= 8.0.0'}
deprecated: '**IMPORTANT 10x+ PERFORMANCE UPGRADE**: Please upgrade to v12.0.1+ as we have fixed an issue with debuglog causing 10x slower router benchmark performance, see https://github.com/koajs/router/pull/173'
dependencies:
- debug: 4.3.5
+ debug: 4.4.0(supports-color@8.1.1)
http-errors: 1.8.1
koa-compose: 4.1.0
methods: 1.1.2
@@ -12965,7 +13469,7 @@ packages:
resolution: {integrity: sha512-gaDdj3GtzoLoeosacd50kBBTnnh3B9AYxDThQUo4sfUyXdOhY6ku1qyZKW88tQCRgc3Sw6ChXYXWZwwgjOxE0w==}
engines: {node: '>= 12'}
dependencies:
- debug: 4.3.5
+ debug: 4.4.0(supports-color@8.1.1)
http-errors: 2.0.0
koa-compose: 4.1.0
methods: 1.1.2
@@ -12977,7 +13481,7 @@ packages:
resolution: {integrity: sha512-tmcyQ/wXXuxpDxyNXv5yNNkdAMdFRqwtegBXUaowiQzUKqJehttS0x2j0eOZDQAyloAth5w6wwBImnFzkUz3pQ==}
engines: {node: '>= 8'}
dependencies:
- debug: 4.3.5
+ debug: 4.4.0(supports-color@8.1.1)
http-errors: 1.8.1
resolve-path: 1.4.0
transitivePeerDependencies:
@@ -13073,7 +13577,7 @@ packages:
content-disposition: 0.5.4
content-type: 1.0.5
cookies: 0.9.1
- debug: 4.3.5
+ debug: 4.4.0(supports-color@8.1.1)
delegates: 1.0.0
depd: 2.0.0
destroy: 1.2.0
@@ -13097,6 +13601,13 @@ packages:
/kuler@2.0.0:
resolution: {integrity: sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==}
+ /latest-version@5.1.0:
+ resolution: {integrity: sha512-weT+r0kTkRQdCdYCNtkMwWXQTMEswKrFBkm4ckQOMVhhqhIMI1UT2hMj+1iigIhgSZm5gTmrRXBNoGUgaTY1xA==}
+ engines: {node: '>=8'}
+ dependencies:
+ package-json: 6.5.0
+ dev: false
+
/lcid@1.0.0:
resolution: {integrity: sha512-YiGkH6EnGrDGqLMITnGjXtGmNtjoXw9SVUzcaos8RBi7Ps0VBylkq+vOcY9QE5poLasPCR849ucFUkl0UzUyOw==}
engines: {node: '>=0.10.0'}
@@ -13104,6 +13615,13 @@ packages:
invert-kv: 1.0.0
dev: true
+ /lcid@2.0.0:
+ resolution: {integrity: sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==}
+ engines: {node: '>=6'}
+ dependencies:
+ invert-kv: 2.0.0
+ dev: false
+
/level-codec@7.0.1:
resolution: {integrity: sha512-Ua/R9B9r3RasXdRmOtd+t9TCOEIIlts+TN/7XTT2unhDaL6sJn83S3rUyljbr6lVtw49N3/yA0HHjpV6Kzb2aQ==}
requiresBuild: true
@@ -13256,6 +13774,11 @@ packages:
xtend: 4.0.2
dev: true
+ /leven@3.1.0:
+ resolution: {integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==}
+ engines: {node: '>=6'}
+ dev: false
+
/levn@0.2.5:
resolution: {integrity: sha512-mvp+NO++YH0B+e8cC/SvJxk6k5Z9Ngd3iXuz7tmT8vZCyQZj/5SI1GkFOiZGGPkm5wWGI9SUrqiAfPq7BJH+0w==}
engines: {node: '>= 0.8.0'}
@@ -13332,12 +13855,19 @@ packages:
path-exists: 3.0.0
dev: true
+ /locate-path@3.0.0:
+ resolution: {integrity: sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==}
+ engines: {node: '>=6'}
+ dependencies:
+ p-locate: 3.0.0
+ path-exists: 3.0.0
+ dev: false
+
/locate-path@6.0.0:
resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==}
engines: {node: '>=10'}
dependencies:
p-locate: 5.0.0
- dev: true
/lodash.assign@4.2.0:
resolution: {integrity: sha512-hFuH8TY+Yji7Eja3mGiuAxBqLagejScbG8GbG0j6o9vzn0YL14My+ktnqtZgFTosKymC9/44wP6s7xyuLfnClw==}
@@ -13355,7 +13885,7 @@ packages:
/lodash.isequal@4.5.0:
resolution: {integrity: sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==}
deprecated: This package is deprecated. Use require('node:util').isDeepStrictEqual instead.
- dev: true
+ dev: false
/lodash.merge@4.6.2:
resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==}
@@ -13387,7 +13917,6 @@ packages:
dependencies:
chalk: 4.1.2
is-unicode-supported: 0.1.0
- dev: true
/logform@2.6.1:
resolution: {integrity: sha512-CdaO738xRapbKIMVn2m4F6KTj4j7ooJ8POVnebSgKo3KBz5axNXRAL7ZdRjIV6NOr2Uf4vjtRkxrFETOioCqSA==}
@@ -13460,12 +13989,10 @@ packages:
/lowercase-keys@1.0.1:
resolution: {integrity: sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==}
engines: {node: '>=0.10.0'}
- dev: true
/lowercase-keys@2.0.0:
resolution: {integrity: sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==}
engines: {node: '>=8'}
- dev: true
/lowercase-keys@3.0.0:
resolution: {integrity: sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==}
@@ -13503,13 +14030,17 @@ packages:
dev: false
optional: true
+ /lru-cache@7.18.3:
+ resolution: {integrity: sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==}
+ engines: {node: '>=12'}
+ dev: false
+
/lru-cache@9.1.2:
resolution: {integrity: sha512-ERJq3FOzJTxBbFjZ7iDs+NiK4VI9Wz+RdrrAB8dio1oV+YvdPzUEE4QNiT2VD51DkIbCYRUUzCRkssXCHqSnKQ==}
engines: {node: 14 || >=16.14}
/lru_map@0.3.3:
resolution: {integrity: sha512-Pn9cox5CsMYngeDbmChANltQl+5pi6XmTrraMSzhPmMBbmgcxmqWry0U3PGapCU1yB4/LqCcom7qhHZiF/jGfQ==}
- dev: true
/ltgt@2.1.3:
resolution: {integrity: sha512-5VjHC5GsENtIi5rbJd+feEpDKhfr7j0odoUR2Uh978g+2p93nd5o34cTjQWohXsPsCZeqoDnIqEf88mPCe0Pfw==}
@@ -13524,6 +14055,13 @@ packages:
resolution: {integrity: sha512-zobTr7akeGHnv7eBOXcRgMeCP6+uyYsczwmeRCauvpvaAltgNyTbLH/+VaEAPUeWBT+1GuNmz4wC/6jtQzbbVA==}
engines: {node: '>=12'}
+ /make-dir@3.1.0:
+ resolution: {integrity: sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==}
+ engines: {node: '>=8'}
+ dependencies:
+ semver: 6.3.1
+ dev: false
+
/make-error@1.3.6:
resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==}
@@ -13554,6 +14092,13 @@ packages:
dev: false
optional: true
+ /map-age-cleaner@0.1.3:
+ resolution: {integrity: sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==}
+ engines: {node: '>=6'}
+ dependencies:
+ p-defer: 1.0.0
+ dev: false
+
/map-cache@0.2.2:
resolution: {integrity: sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg==}
engines: {node: '>=0.10.0'}
@@ -13603,7 +14148,6 @@ packages:
/math-intrinsics@1.1.0:
resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==}
engines: {node: '>= 0.4'}
- dev: true
/math-random@1.0.4:
resolution: {integrity: sha512-rUxjysqif/BZQH2yhd5Aaq7vXMSx9NdEsQcyA07uEzIvxgI7zIr33gGsh+RU0/XjmQpCW7RsVof1vlkvQVCK5A==}
@@ -13635,6 +14179,15 @@ packages:
mimic-fn: 1.2.0
dev: true
+ /mem@4.3.0:
+ resolution: {integrity: sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w==}
+ engines: {node: '>=6'}
+ dependencies:
+ map-age-cleaner: 0.1.3
+ mimic-fn: 2.1.0
+ p-is-promise: 2.1.0
+ dev: false
+
/memdown@1.4.1:
resolution: {integrity: sha512-iVrGHZB8i4OQfM155xx8akvG9FIj+ht14DX5CQkCTG4EHzZ3d3sgckIf/Lm9ivZalEsFuEVnWv2B2WZvbrro2w==}
requiresBuild: true
@@ -13662,7 +14215,6 @@ packages:
/memorystream@0.3.1:
resolution: {integrity: sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==}
engines: {node: '>= 0.10.0'}
- dev: true
/merge-descriptors@1.0.1:
resolution: {integrity: sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==}
@@ -13670,7 +14222,6 @@ packages:
/merge-descriptors@1.0.3:
resolution: {integrity: sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==}
- dev: true
/merge2@1.4.1:
resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==}
@@ -13794,10 +14345,14 @@ packages:
engines: {node: '>=4'}
dev: true
+ /mimic-fn@2.1.0:
+ resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==}
+ engines: {node: '>=6'}
+ dev: false
+
/mimic-response@1.0.1:
resolution: {integrity: sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==}
engines: {node: '>=4'}
- dev: true
/mimic-response@2.1.0:
resolution: {integrity: sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA==}
@@ -13843,7 +14398,6 @@ packages:
resolution: {integrity: sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==}
dependencies:
brace-expansion: 1.1.11
- dev: true
/minimatch@3.1.2:
resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==}
@@ -13857,6 +14411,13 @@ packages:
dependencies:
brace-expansion: 2.0.1
+ /minimatch@8.0.4:
+ resolution: {integrity: sha512-W0Wvr9HyFXZRGIDgCicunpQ299OKXs9RgZfaukz4qAW/pJhcpUfupc9c+OObPOFueNy8VSrZgEmDtk6Kh4WzDA==}
+ engines: {node: '>=16 || 14 >=14.17'}
+ dependencies:
+ brace-expansion: 2.0.1
+ dev: false
+
/minimatch@9.0.1:
resolution: {integrity: sha512-0jWhJpD/MdhPXwPuiRkCbfYfSKp2qnn2eOc279qI7f+osl/l+prKSrvhg157zSYvx/1nmgn2NqdT6k2Z7zSH9w==}
engines: {node: '>=16 || 14 >=14.17'}
@@ -13939,6 +14500,11 @@ packages:
yallist: 4.0.0
dev: false
+ /minipass@4.2.8:
+ resolution: {integrity: sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ==}
+ engines: {node: '>=8'}
+ dev: false
+
/minipass@5.0.0:
resolution: {integrity: sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==}
engines: {node: '>=8'}
@@ -14012,7 +14578,6 @@ packages:
resolution: {integrity: sha512-bZTFT5rrPKtPJxj8KSV0WkPyNxl72vQepqqVUAW2ARUpUSF2qXMB6jZj7hW5/k7C1rtpzqbD/IIbJwLXUjCHeg==}
dependencies:
obliterator: 2.0.5
- dev: true
/mocha-circleci-reporter@0.0.3:
resolution: {integrity: sha512-sZHmd+HH0pgQjTdk0itV2+RSOikqLo7kravRLKTmzcvyu9lA69pXd4KLAv5NMcF4c3EnSatX0iBSM4gSXFYjEw==}
@@ -14063,7 +14628,6 @@ packages:
yargs: 16.2.0
yargs-parser: 20.2.9
yargs-unparser: 2.0.0
- dev: true
/mocha@4.1.0:
resolution: {integrity: sha512-0RVnjg1HJsXY2YFDoTNzcc1NKhYuXKRrBAG2gDygmJJA136Cs2QlRliZG1mA0ap7cuaT30mw16luAeln+4RiNA==}
@@ -14204,10 +14768,20 @@ packages:
imul: 1.0.1
dev: true
+ /mustache@3.2.1:
+ resolution: {integrity: sha512-RERvMFdLpaFfSRIEe632yDm5nsd0SDKn8hGmcUwswnyiE5mtdZLDybtHAz6hjJhawokF0hXvGLtx9mrQfm6FkA==}
+ engines: {npm: '>=1.4.0'}
+ hasBin: true
+ dev: false
+
/mustache@4.2.0:
resolution: {integrity: sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ==}
hasBin: true
+ /mute-stream@0.0.8:
+ resolution: {integrity: sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==}
+ dev: false
+
/mz@2.7.0:
resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==}
dependencies:
@@ -14292,6 +14866,11 @@ packages:
resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==}
dev: true
+ /netmask@2.0.2:
+ resolution: {integrity: sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==}
+ engines: {node: '>= 0.4.0'}
+ dev: false
+
/next-tick@1.1.0:
resolution: {integrity: sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==}
dev: true
@@ -14310,7 +14889,6 @@ packages:
/nice-try@1.0.5:
resolution: {integrity: sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==}
- dev: true
/no-case@2.3.2:
resolution: {integrity: sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ==}
@@ -14374,6 +14952,13 @@ packages:
lodash: 4.17.21
dev: true
+ /node-fetch-h2@2.3.0:
+ resolution: {integrity: sha512-ofRW94Ab0T4AOh5Fk8t0h8OBWrmjb0SSB20xh1H8YnPV9EJ+f5AMoYSUQ2zgJ4Iq2HAK0I2l5/Nequ8YzFS3Hg==}
+ engines: {node: 4.x || >=6.0.0}
+ dependencies:
+ http2-client: 1.3.5
+ dev: false
+
/node-fetch@1.7.3:
resolution: {integrity: sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==}
requiresBuild: true
@@ -14479,6 +15064,29 @@ packages:
prebuild-install: 7.1.3
dev: true
+ /node-readfiles@0.2.0:
+ resolution: {integrity: sha512-SU00ZarexNlE4Rjdm83vglt5Y9yiQ+XI1XpflWlb7q7UTN1JUItm69xMeiQCTxtTfnzt+83T8Cx+vI2ED++VDA==}
+ dependencies:
+ es6-promise: 3.3.1
+ dev: false
+
+ /nodemon@3.1.9:
+ resolution: {integrity: sha512-hdr1oIb2p6ZSxu3PB2JWWYS7ZQ0qvaZsc3hK8DR8f02kRzc8rjYmxAIvdz+aYC+8F2IjNaB7HMcSDg8nQpJxyg==}
+ engines: {node: '>=10'}
+ hasBin: true
+ dependencies:
+ chokidar: 3.6.0
+ debug: 4.4.0(supports-color@5.5.0)
+ ignore-by-default: 1.0.1
+ minimatch: 3.1.2
+ pstree.remy: 1.1.8
+ semver: 7.6.3
+ simple-update-notifier: 2.0.0
+ supports-color: 5.5.0
+ touch: 3.1.1
+ undefsafe: 2.0.5
+ dev: true
+
/nofilter@1.0.4:
resolution: {integrity: sha512-N8lidFp+fCz+TD51+haYdbDGrcBWwuHX40F5+z0qkUjMJ5Tp+rdSuAkMJ9N9eoolDlEVTf6u5icM+cNKkKW2mA==}
engines: {node: '>=8'}
@@ -14541,12 +15149,10 @@ packages:
/normalize-path@3.0.0:
resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==}
engines: {node: '>=0.10.0'}
- dev: true
/normalize-url@4.5.1:
resolution: {integrity: sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA==}
engines: {node: '>=8'}
- dev: true
/normalize-url@6.1.0:
resolution: {integrity: sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==}
@@ -14558,7 +15164,6 @@ packages:
engines: {node: '>=4'}
dependencies:
path-key: 2.0.1
- dev: true
/npmlog@4.1.2:
resolution: {integrity: sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==}
@@ -14599,7 +15204,6 @@ packages:
/number-is-nan@1.0.1:
resolution: {integrity: sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ==}
engines: {node: '>=0.10.0'}
- dev: true
/number-to-bn@1.7.0:
resolution: {integrity: sha512-wsJ9gfSz1/s4ZsJN01lyonwuxA1tml6X1yBDnfpMglypcBRFZZkus26EdPSlqS5GJfYddVZa22p3VNb3z5m5Ig==}
@@ -14608,14 +15212,72 @@ packages:
bn.js: 4.11.6
strip-hex-prefix: 1.0.0
+ /nunjucks@3.2.4:
+ resolution: {integrity: sha512-26XRV6BhkgK0VOxfbU5cQI+ICFUtMLixv1noZn1tGU38kQH5A5nmmbk/O45xdyBhD1esk47nKrY0mvQpZIhRjQ==}
+ engines: {node: '>= 6.9.0'}
+ hasBin: true
+ peerDependencies:
+ chokidar: ^3.3.0
+ peerDependenciesMeta:
+ chokidar:
+ optional: true
+ dependencies:
+ a-sync-waterfall: 1.0.1
+ asap: 2.0.6
+ commander: 5.1.0
+ dev: false
+
/o3@1.0.3:
resolution: {integrity: sha512-f+4n+vC6s4ysy7YO7O2gslWZBUu8Qj2i2OUJOvjRxQva7jVjYjB29jrr9NCjmxZQR0gzrOcv1RnqoYOeMs5VRQ==}
dependencies:
capability: 0.2.5
+ /oas-kit-common@1.0.8:
+ resolution: {integrity: sha512-pJTS2+T0oGIwgjGpw7sIRU8RQMcUoKCDWFLdBqKB2BNmGpbBMH2sdqAaOXUg8OzonZHU0L7vfJu1mJFEiYDWOQ==}
+ dependencies:
+ fast-safe-stringify: 2.1.1
+ dev: false
+
+ /oas-linter@3.2.2:
+ resolution: {integrity: sha512-KEGjPDVoU5K6swgo9hJVA/qYGlwfbFx+Kg2QB/kd7rzV5N8N5Mg6PlsoCMohVnQmo+pzJap/F610qTodKzecGQ==}
+ dependencies:
+ '@exodus/schemasafe': 1.3.0
+ should: 13.2.3
+ yaml: 1.10.2
+ dev: false
+
+ /oas-resolver@2.5.6:
+ resolution: {integrity: sha512-Yx5PWQNZomfEhPPOphFbZKi9W93CocQj18NlD2Pa4GWZzdZpSJvYwoiuurRI7m3SpcChrnO08hkuQDL3FGsVFQ==}
+ hasBin: true
+ dependencies:
+ node-fetch-h2: 2.3.0
+ oas-kit-common: 1.0.8
+ reftools: 1.1.9
+ yaml: 1.10.2
+ yargs: 17.7.2
+ dev: false
+
+ /oas-schema-walker@1.1.5:
+ resolution: {integrity: sha512-2yucenq1a9YPmeNExoUa9Qwrt9RFkjqaMAA1X+U7sbb0AqBeTIdMHky9SQQ6iN94bO5NW0W4TRYXerG+BdAvAQ==}
+ dev: false
+
+ /oas-validator@3.4.0:
+ resolution: {integrity: sha512-l/SxykuACi2U51osSsBXTxdsFc8Fw41xI7AsZkzgVgWJAzoEFaaNptt35WgY9C3757RUclsm6ye5GvSyYoozLQ==}
+ dependencies:
+ ajv: 5.5.2
+ better-ajv-errors: 0.6.7(ajv@5.5.2)
+ call-me-maybe: 1.0.2
+ oas-kit-common: 1.0.8
+ oas-linter: 3.2.2
+ oas-resolver: 2.5.6
+ oas-schema-walker: 1.1.5
+ reftools: 1.1.9
+ should: 13.2.3
+ yaml: 1.10.2
+ dev: false
+
/oauth-sign@0.9.0:
resolution: {integrity: sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==}
- dev: true
/object-assign@4.1.1:
resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==}
@@ -14642,7 +15304,6 @@ packages:
/object-inspect@1.13.3:
resolution: {integrity: sha512-kDCGIbxkDSXE3euJZZXzc6to7fCrKHNI/hSRQnRuQ+BWjFNzZwiFF8fj/6o2t2G9/jTj8PSIYTfCLelLZEeRpA==}
engines: {node: '>= 0.4'}
- dev: true
/object-is@1.1.6:
resolution: {integrity: sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q==}
@@ -14768,7 +15429,6 @@ packages:
/obliterator@2.0.5:
resolution: {integrity: sha512-42CPE9AhahZRsMNslczq0ctAEtqk8Eka26QofnqC346BZdHDySk3LWka23LI7ULIw11NmltpiLagIq8gBozxTw==}
- dev: true
/oboe@2.1.4:
resolution: {integrity: sha512-ymBJ4xSC6GBXLT9Y7lirj+xbqBLa+jADGJldGEYG7u8sZbS9GyG+u1Xk9c5cbriKwSpCg41qUhPjvU5xOpvIyQ==}
@@ -14800,6 +15460,13 @@ packages:
dependencies:
fn.name: 1.1.0
+ /onetime@5.1.2:
+ resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==}
+ engines: {node: '>=6'}
+ dependencies:
+ mimic-fn: 2.1.0
+ dev: false
+
/only@0.0.2:
resolution: {integrity: sha512-Fvw+Jemq5fjjyWz6CpKx6w9s7xxqo3+JCyM0WXWeCSOboZ8ABkyvP8ID4CZuChA/wxSx+XSJmdOm8rGVyJ1hdQ==}
@@ -14811,6 +15478,30 @@ packages:
is-wsl: 2.2.0
dev: true
+ /openapi-generator@0.1.39(ajv@6.12.6):
+ resolution: {integrity: sha512-/i5245hUAXRyYmX1tWy+ftKtU5G8me2QNyjNS670GUSzTVDnhAWc+uYBZWccsvPH26mvEDnj1sTpfUefLiXPZQ==}
+ hasBin: true
+ dependencies:
+ '@types/nunjucks': 3.2.6
+ '@types/request': 2.48.12
+ colorful: 2.1.0
+ commander: 2.20.3
+ debug: 4.4.0(supports-color@8.1.1)
+ nunjucks: 3.2.4
+ openapi3-ts: 1.4.0
+ request: 2.88.2
+ swagger2openapi: 5.4.0(ajv@6.12.6)
+ tslib: 1.14.1
+ transitivePeerDependencies:
+ - ajv
+ - chokidar
+ - supports-color
+ dev: false
+
+ /openapi3-ts@1.4.0:
+ resolution: {integrity: sha512-8DmE2oKayvSkIR3XSZ4+pRliBsx19bSNeIzkTPswY8r4wvjX86bMxsORdqwAwMxE8PefOcSAT2auvi/0TZe9yA==}
+ dev: false
+
/optimism@0.18.1:
resolution: {integrity: sha512-mLXNwWPa9dgFyDqkNi54sjDyNJ9/fTI6WGBLgnXku1vdKY/jovHfZT5r+aiVeFFLOz+foPNOm5YJ4mqgld2GBQ==}
requiresBuild: true
@@ -14857,6 +15548,21 @@ packages:
word-wrap: 1.2.5
dev: true
+ /ora@5.4.1:
+ resolution: {integrity: sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==}
+ engines: {node: '>=10'}
+ dependencies:
+ bl: 4.1.0
+ chalk: 4.1.2
+ cli-cursor: 3.1.0
+ cli-spinners: 2.9.2
+ is-interactive: 1.0.0
+ is-unicode-supported: 0.1.0
+ log-symbols: 4.1.0
+ strip-ansi: 6.0.1
+ wcwidth: 1.0.1
+ dev: false
+
/os-homedir@1.0.2:
resolution: {integrity: sha512-B5JU3cabzk8c67mRRd3ECmROafjYMXbuzlwtqdM8IbS8ktlTix8aFGb2bAGKrSRIlnfKwovGUUr72JUPyOb6kQ==}
engines: {node: '>=0.10.0'}
@@ -14879,6 +15585,15 @@ packages:
mem: 1.1.0
dev: true
+ /os-locale@3.1.0:
+ resolution: {integrity: sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==}
+ engines: {node: '>=6'}
+ dependencies:
+ execa: 1.0.0
+ lcid: 2.0.0
+ mem: 4.3.0
+ dev: false
+
/os-shim@0.1.3:
resolution: {integrity: sha512-jd0cvB8qQ5uVt0lvCIexBaROw1KyKm5sbulg2fWOHjETisuCzWyt+eTZKEMs8v6HwzoGs8xik26jg7eCM6pS+A==}
engines: {node: '>= 0.4.0'}
@@ -14887,7 +15602,6 @@ packages:
/os-tmpdir@1.0.2:
resolution: {integrity: sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==}
engines: {node: '>=0.10.0'}
- dev: true
/own-keys@1.0.1:
resolution: {integrity: sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==}
@@ -14901,7 +15615,6 @@ packages:
/p-cancelable@1.1.0:
resolution: {integrity: sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==}
engines: {node: '>=6'}
- dev: true
/p-cancelable@2.1.1:
resolution: {integrity: sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==}
@@ -14913,10 +15626,19 @@ packages:
engines: {node: '>=12.20'}
dev: true
+ /p-defer@1.0.0:
+ resolution: {integrity: sha512-wB3wfAxZpk2AzOfUMJNL+d36xothRSyj8EXOa4f6GMqYDN9BJaaSISbsk+wS9abmnebVw95C2Kb5t85UmpCxuw==}
+ engines: {node: '>=4'}
+ dev: false
+
/p-finally@1.0.0:
resolution: {integrity: sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==}
engines: {node: '>=4'}
- dev: true
+
+ /p-is-promise@2.1.0:
+ resolution: {integrity: sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg==}
+ engines: {node: '>=6'}
+ dev: false
/p-limit@1.3.0:
resolution: {integrity: sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==}
@@ -14925,12 +15647,18 @@ packages:
p-try: 1.0.0
dev: true
+ /p-limit@2.3.0:
+ resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==}
+ engines: {node: '>=6'}
+ dependencies:
+ p-try: 2.2.0
+ dev: false
+
/p-limit@3.1.0:
resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==}
engines: {node: '>=10'}
dependencies:
yocto-queue: 0.1.0
- dev: true
/p-locate@2.0.0:
resolution: {integrity: sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==}
@@ -14939,12 +15667,18 @@ packages:
p-limit: 1.3.0
dev: true
+ /p-locate@3.0.0:
+ resolution: {integrity: sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==}
+ engines: {node: '>=6'}
+ dependencies:
+ p-limit: 2.3.0
+ dev: false
+
/p-locate@5.0.0:
resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==}
engines: {node: '>=10'}
dependencies:
p-limit: 3.1.0
- dev: true
/p-map@4.0.0:
resolution: {integrity: sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==}
@@ -14958,9 +15692,48 @@ packages:
engines: {node: '>=4'}
dev: true
+ /p-try@2.2.0:
+ resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==}
+ engines: {node: '>=6'}
+ dev: false
+
+ /pac-proxy-agent@7.1.0:
+ resolution: {integrity: sha512-Z5FnLVVZSnX7WjBg0mhDtydeRZ1xMcATZThjySQUHqr+0ksP8kqaw23fNKkaaN/Z8gwLUs/W7xdl0I75eP2Xyw==}
+ engines: {node: '>= 14'}
+ dependencies:
+ '@tootallnate/quickjs-emscripten': 0.23.0
+ agent-base: 7.1.3
+ debug: 4.4.0(supports-color@8.1.1)
+ get-uri: 6.0.4
+ http-proxy-agent: 7.0.2
+ https-proxy-agent: 7.0.6
+ pac-resolver: 7.0.1
+ socks-proxy-agent: 8.0.5
+ transitivePeerDependencies:
+ - supports-color
+ dev: false
+
+ /pac-resolver@7.0.1:
+ resolution: {integrity: sha512-5NPgf87AT2STgwa2ntRMr45jTKrYBGkVU36yT0ig/n/GMAa3oPqhZfIQ2kMEimReg0+t9kZViDVZ83qfVUlckg==}
+ engines: {node: '>= 14'}
+ dependencies:
+ degenerator: 5.0.1
+ netmask: 2.0.2
+ dev: false
+
/package-json-from-dist@1.0.1:
resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==}
+ /package-json@6.5.0:
+ resolution: {integrity: sha512-k3bdm2n25tkyxcjSKzB5x8kfVxlMdgsbPr0GkZcwHsLpba6cBjqCt1KlcChKEvxHIcTB1FVMuwoijZ26xex5MQ==}
+ engines: {node: '>=8'}
+ dependencies:
+ got: 9.6.0
+ registry-auth-token: 4.2.2
+ registry-url: 5.1.0
+ semver: 6.3.1
+ dev: false
+
/pako@1.0.11:
resolution: {integrity: sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==}
dev: true
@@ -15126,12 +15899,10 @@ packages:
/path-exists@3.0.0:
resolution: {integrity: sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==}
engines: {node: '>=4'}
- dev: true
/path-exists@4.0.0:
resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==}
engines: {node: '>=8'}
- dev: true
/path-is-absolute@1.0.1:
resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==}
@@ -15141,7 +15912,6 @@ packages:
/path-key@2.0.1:
resolution: {integrity: sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==}
engines: {node: '>=4'}
- dev: true
/path-key@3.1.1:
resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==}
@@ -15159,12 +15929,15 @@ packages:
/path-to-regexp@0.1.12:
resolution: {integrity: sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==}
- dev: true
/path-to-regexp@0.1.7:
resolution: {integrity: sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==}
dev: false
+ /path-to-regexp@3.3.0:
+ resolution: {integrity: sha512-qyCH421YQPS2WFDxDjftfc1ZR5WKQzVzqsp4n9M2kQhVOo/ByahFoUNJfl58kOcEGfQ//7weFTDhm+ss8Ecxgw==}
+ dev: false
+
/path-to-regexp@6.2.2:
resolution: {integrity: sha512-GQX3SSMokngb36+whdpRXE+3f9V8UzyAorlYvOGx87ufGHehNTn5lCxrKtLyZ4Yl/wEKnNnr98ZzOwwDZV5ogw==}
@@ -15204,25 +15977,20 @@ packages:
/performance-now@2.1.0:
resolution: {integrity: sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==}
- dev: true
/picocolors@1.0.1:
resolution: {integrity: sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==}
- dev: true
/picocolors@1.1.1:
resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==}
- dev: true
/picomatch@2.3.1:
resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==}
engines: {node: '>=8.6'}
- dev: true
/picomatch@4.0.2:
resolution: {integrity: sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==}
engines: {node: '>=12'}
- dev: true
/pify@2.3.0:
resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==}
@@ -15377,7 +16145,6 @@ packages:
/prepend-http@2.0.0:
resolution: {integrity: sha512-ravE6m9Atw9Z/jjttRUZ+clIXogdghyZAuWJ3qEzjT+jI/dL1ifAqhZeC5VHzQp1MSt1+jxKkFNemj/iO7tVUA==}
engines: {node: '>=4'}
- dev: true
/preserve@0.2.0:
resolution: {integrity: sha512-s/46sYeylUfHNjI+sA/78FAHlmIuKqI9wNnzEOGehAlUUYeObv5C2mOinXBjyUyWmJ2SfcS2/ydApH4hTF4WXQ==}
@@ -15539,7 +16306,7 @@ packages:
'@protobufjs/pool': 1.1.0
'@protobufjs/utf8': 1.1.0
'@types/long': 4.0.2
- '@types/node': 22.10.10
+ '@types/node': 20.17.16
long: 4.0.0
/protobufjs@7.3.2:
@@ -15557,7 +16324,7 @@ packages:
'@protobufjs/path': 1.1.2
'@protobufjs/pool': 1.1.0
'@protobufjs/utf8': 1.1.0
- '@types/node': 22.10.10
+ '@types/node': 20.17.16
long: 5.2.3
/protobufjs@7.4.0:
@@ -15585,6 +16352,22 @@ packages:
forwarded: 0.2.0
ipaddr.js: 1.9.1
+ /proxy-agent@6.4.0:
+ resolution: {integrity: sha512-u0piLU+nCOHMgGjRbimiXmA9kM/L9EHh3zL81xCdp7m+Y2pHIsnmbdDoEDoAz5geaonNR6q6+yOPQs6n4T6sBQ==}
+ engines: {node: '>= 14'}
+ dependencies:
+ agent-base: 7.1.3
+ debug: 4.4.0(supports-color@8.1.1)
+ http-proxy-agent: 7.0.2
+ https-proxy-agent: 7.0.6
+ lru-cache: 7.18.3
+ pac-proxy-agent: 7.1.0
+ proxy-from-env: 1.1.0
+ socks-proxy-agent: 8.0.5
+ transitivePeerDependencies:
+ - supports-color
+ dev: false
+
/proxy-from-env@1.1.0:
resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==}
@@ -15599,6 +16382,9 @@ packages:
/psl@1.9.0:
resolution: {integrity: sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==}
+
+ /pstree.remy@1.1.8:
+ resolution: {integrity: sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==}
dev: true
/public-encrypt@4.0.3:
@@ -15665,7 +16451,6 @@ packages:
dependencies:
end-of-stream: 1.4.4
once: 1.4.0
- dev: true
/punycode@1.4.1:
resolution: {integrity: sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==}
@@ -15679,7 +16464,13 @@ packages:
/punycode@2.3.1:
resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==}
engines: {node: '>=6'}
- dev: true
+
+ /pupa@2.1.1:
+ resolution: {integrity: sha512-l1jNAspIBSFqbT+y+5FosojNpVpF94nlI+wDUpqP9enwOTfHx9f0gh5nB96vl+6yTpsJsypeNrwfzPrKuHB41A==}
+ engines: {node: '>=8'}
+ dependencies:
+ escape-goat: 2.1.1
+ dev: false
/pure-rand@5.0.5:
resolution: {integrity: sha512-BwQpbqxSCBJVpamI6ydzcKqyFmnd5msMWUGvzXLm1aXvusbbgkbOto/EUPM00hjveJEaJtdbhUjKSzWRhQVkaw==}
@@ -15713,7 +16504,6 @@ packages:
engines: {node: '>=0.6'}
dependencies:
side-channel: 1.1.0
- dev: true
/qs@6.14.0:
resolution: {integrity: sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==}
@@ -15725,7 +16515,6 @@ packages:
/qs@6.5.3:
resolution: {integrity: sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==}
engines: {node: '>=0.6'}
- dev: true
/query-string@5.1.1:
resolution: {integrity: sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw==}
@@ -15826,7 +16615,6 @@ packages:
inherits: 2.0.4
isarray: 0.0.1
string_decoder: 0.10.31
- dev: true
/readable-stream@2.3.8:
resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==}
@@ -15863,12 +16651,10 @@ packages:
engines: {node: '>=8.10.0'}
dependencies:
picomatch: 2.3.1
- dev: true
/readdirp@4.1.1:
resolution: {integrity: sha512-h80JrZu/MHUZCyHu5ciuoI0+WxsCxzxJTILn6Fs8rxSnFPh+UVHYfeIxK1nVGugMqkfC4vJcBOYbkfkwYK0+gw==}
engines: {node: '>= 14.18.0'}
- dev: true
/readonly-date@1.0.0:
resolution: {integrity: sha512-tMKIV7hlk0h4mO3JTmmVuIlJVXjKk3Sep9Bf5OH0O+758ruuVkUy2J9SttDLm91IEX/WHlXPSpxMGjPj4beMIQ==}
@@ -15907,6 +16693,10 @@ packages:
dependencies:
redis-errors: 1.2.0
+ /reflect-metadata@0.1.13:
+ resolution: {integrity: sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==}
+ dev: false
+
/reflect.getprototypeof@1.0.10:
resolution: {integrity: sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==}
engines: {node: '>= 0.4'}
@@ -15921,6 +16711,10 @@ packages:
which-builtin-type: 1.2.1
dev: true
+ /reftools@1.1.9:
+ resolution: {integrity: sha512-OVede/NQE13xBQ+ob5CKd5KyeJYU2YInb1bmV4nRoOfquZPkAkxuOXicSe1PvqIuZZ4kD13sPKBbR7UFDmli6w==}
+ dev: false
+
/regenerate@1.4.2:
resolution: {integrity: sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==}
requiresBuild: true
@@ -15995,10 +16789,24 @@ packages:
resolution: {integrity: sha512-tJ9+S4oKjxY8IZ9jmjnp/mtytu1u3iyIQAfmI51IKWH6bFf7XR1ybtaO6j7INhZKXOTYADk7V5qxaqLkmNxiZQ==}
requiresBuild: true
dependencies:
- regenerate: 1.4.2
- regjsgen: 0.2.0
- regjsparser: 0.1.5
- dev: true
+ regenerate: 1.4.2
+ regjsgen: 0.2.0
+ regjsparser: 0.1.5
+ dev: true
+
+ /registry-auth-token@4.2.2:
+ resolution: {integrity: sha512-PC5ZysNb42zpFME6D/XlIgtNGdTl8bBOCw90xQLVMpzuuubJKYDWFAEuUNc+Cn8Z8724tg2SDhDRrkVEsqfDMg==}
+ engines: {node: '>=6.0.0'}
+ dependencies:
+ rc: 1.2.8
+ dev: false
+
+ /registry-url@5.1.0:
+ resolution: {integrity: sha512-8acYXXTI0AkQv6RAOjE3vOaIXZkT9wo4LOFbBKYQEEnnMNBpKqdUrI6S4NT0KPIo/WVvJ5tE/X5LF/TQUf0ekw==}
+ engines: {node: '>=8'}
+ dependencies:
+ rc: 1.2.8
+ dev: false
/regjsgen@0.2.0:
resolution: {integrity: sha512-x+Y3yA24uF68m5GA+tBjbGYo64xXVJpbToBaWCoSNSc1hdk6dfctaRWrNFTVJZIIhL5GxW8zwjoixbnifnK59g==}
@@ -16111,7 +16919,6 @@ packages:
tough-cookie: 2.5.0
tunnel-agent: 0.6.0
uuid: 3.4.0
- dev: true
/require-directory@2.1.1:
resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==}
@@ -16129,7 +16936,6 @@ packages:
/require-main-filename@1.0.1:
resolution: {integrity: sha512-IqSUtOVP4ksd1C/ej5zeEh/BIP2ajqpn8c5x+q99gvcIG/Qf0cud5raVnE/Dwd0ua9TXYDoDc0RE5hBSdz22Ug==}
- dev: true
/resolve-alpn@1.2.1:
resolution: {integrity: sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==}
@@ -16169,7 +16975,6 @@ packages:
resolution: {integrity: sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==}
dependencies:
path-parse: 1.0.7
- dev: true
/resolve@1.22.10:
resolution: {integrity: sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==}
@@ -16202,7 +17007,6 @@ packages:
resolution: {integrity: sha512-/Fpe5guzJk1gPqdJLJR5u7eG/gNY4nImjbRDaVWVMRhne55TCmj2i9Q+54PBRfatRC8v/rIiv9BN0pMd9OV5EQ==}
dependencies:
lowercase-keys: 1.0.1
- dev: true
/responselike@2.0.1:
resolution: {integrity: sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==}
@@ -16210,6 +17014,14 @@ packages:
lowercase-keys: 2.0.0
dev: true
+ /restore-cursor@3.1.0:
+ resolution: {integrity: sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==}
+ engines: {node: '>=8'}
+ dependencies:
+ onetime: 5.1.2
+ signal-exit: 3.0.7
+ dev: false
+
/ret@0.1.15:
resolution: {integrity: sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==}
engines: {node: '>=0.12'}
@@ -16297,6 +17109,11 @@ packages:
bufferutil: 4.0.9
utf-8-validate: 5.0.10
+ /run-async@2.4.1:
+ resolution: {integrity: sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==}
+ engines: {node: '>=0.12.0'}
+ dev: false
+
/run-parallel@1.2.0:
resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==}
dependencies:
@@ -16314,7 +17131,6 @@ packages:
requiresBuild: true
dependencies:
tslib: 1.14.1
- dev: true
/rxjs@7.8.1:
resolution: {integrity: sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==}
@@ -16487,6 +17303,13 @@ packages:
requiresBuild: true
dev: true
+ /semver-diff@3.1.1:
+ resolution: {integrity: sha512-GX0Ix/CJcHyB8c4ykpHGIAvLyOwOobtM/8d+TQkAd81/bEjgPHrfba41Vpesr7jX/t8Uh+R3EX9eAS5be+jQYg==}
+ engines: {node: '>=8'}
+ dependencies:
+ semver: 6.3.1
+ dev: false
+
/semver@5.4.1:
resolution: {integrity: sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg==}
hasBin: true
@@ -16496,12 +17319,10 @@ packages:
/semver@5.7.2:
resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==}
hasBin: true
- dev: true
/semver@6.3.1:
resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==}
hasBin: true
- dev: true
/semver@7.6.2:
resolution: {integrity: sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==}
@@ -16553,7 +17374,6 @@ packages:
statuses: 2.0.1
transitivePeerDependencies:
- supports-color
- dev: true
/sentence-case@2.1.1:
resolution: {integrity: sha512-ENl7cYHaK/Ktwk5OTD+aDbQ3uC8IByu/6Bkg+HDv8Mm+XnBnppVNalcfJTNsp1ibstKh030/JKQQWglDvtKwEQ==}
@@ -16566,7 +17386,6 @@ packages:
resolution: {integrity: sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==}
dependencies:
randombytes: 2.1.0
- dev: true
/serve-static@1.15.0:
resolution: {integrity: sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==}
@@ -16590,7 +17409,6 @@ packages:
send: 0.19.0
transitivePeerDependencies:
- supports-color
- dev: true
/servify@0.1.12:
resolution: {integrity: sha512-/xE6GvsKKqyo1BAY+KxOWXcLpPsUUyji7Qg3bVD7hh1eRze5bR1uYiuDA/k3Gof1s9BTzQZEJK8sNcNGFIzeWw==}
@@ -16691,7 +17509,6 @@ packages:
engines: {node: '>=0.10.0'}
dependencies:
shebang-regex: 1.0.0
- dev: true
/shebang-command@2.0.0:
resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==}
@@ -16702,12 +17519,16 @@ packages:
/shebang-regex@1.0.0:
resolution: {integrity: sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==}
engines: {node: '>=0.10.0'}
- dev: true
/shebang-regex@3.0.0:
resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==}
engines: {node: '>=8'}
+ /shell-quote@1.8.2:
+ resolution: {integrity: sha512-AzqKpGKjrj7EM6rKVQEPpB288oCfnrEIuyoT9cyF4nmGa7V8Zk6f7RRqYisX8X9m+Q7bd632aZW4ky7EhbQztA==}
+ engines: {node: '>= 0.4'}
+ dev: true
+
/shelljs@0.8.5:
resolution: {integrity: sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==}
engines: {node: '>=4'}
@@ -16723,6 +17544,44 @@ packages:
nanoid: 3.3.8
dev: true
+ /should-equal@2.0.0:
+ resolution: {integrity: sha512-ZP36TMrK9euEuWQYBig9W55WPC7uo37qzAEmbjHz4gfyuXrEUgF8cUvQVO+w+d3OMfPvSRQJ22lSm8MQJ43LTA==}
+ dependencies:
+ should-type: 1.4.0
+ dev: false
+
+ /should-format@3.0.3:
+ resolution: {integrity: sha512-hZ58adtulAk0gKtua7QxevgUaXTTXxIi8t41L3zo9AHvjXO1/7sdLECuHeIN2SRtYXpNkmhoUP2pdeWgricQ+Q==}
+ dependencies:
+ should-type: 1.4.0
+ should-type-adaptors: 1.1.0
+ dev: false
+
+ /should-type-adaptors@1.1.0:
+ resolution: {integrity: sha512-JA4hdoLnN+kebEp2Vs8eBe9g7uy0zbRo+RMcU0EsNy+R+k049Ki+N5tT5Jagst2g7EAja+euFuoXFCa8vIklfA==}
+ dependencies:
+ should-type: 1.4.0
+ should-util: 1.0.1
+ dev: false
+
+ /should-type@1.4.0:
+ resolution: {integrity: sha512-MdAsTu3n25yDbIe1NeN69G4n6mUnJGtSJHygX3+oN0ZbO3DTiATnf7XnYJdGT42JCXurTb1JI0qOBR65shvhPQ==}
+ dev: false
+
+ /should-util@1.0.1:
+ resolution: {integrity: sha512-oXF8tfxx5cDk8r2kYqlkUJzZpDBqVY/II2WhvU0n9Y3XYvAYRmeaf1PvvIvTgPnv4KJ+ES5M0PyDq5Jp+Ygy2g==}
+ dev: false
+
+ /should@13.2.3:
+ resolution: {integrity: sha512-ggLesLtu2xp+ZxI+ysJTmNjh2U0TsC+rQ/pfED9bUZZ4DKefP27D+7YJVVTvKsmjLpIi9jAa7itwDGkDDmt1GQ==}
+ dependencies:
+ should-equal: 2.0.0
+ should-format: 3.0.3
+ should-type: 1.4.0
+ should-type-adaptors: 1.1.0
+ should-util: 1.0.1
+ dev: false
+
/shx@0.3.4:
resolution: {integrity: sha512-N6A9MLVqjxZYcVn8hLmtneQWIJtp8IKzMP4eMnx+nqkvXoqinUPCbUFLp2UcWTEIUONhlk0ewxr/jaVGlc+J+g==}
engines: {node: '>=6'}
@@ -16739,7 +17598,6 @@ packages:
dependencies:
es-errors: 1.3.0
object-inspect: 1.13.3
- dev: true
/side-channel-map@1.0.1:
resolution: {integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==}
@@ -16749,7 +17607,6 @@ packages:
es-errors: 1.3.0
get-intrinsic: 1.2.7
object-inspect: 1.13.3
- dev: true
/side-channel-weakmap@1.0.2:
resolution: {integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==}
@@ -16760,7 +17617,6 @@ packages:
get-intrinsic: 1.2.7
object-inspect: 1.13.3
side-channel-map: 1.0.1
- dev: true
/side-channel@1.0.6:
resolution: {integrity: sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==}
@@ -16780,7 +17636,6 @@ packages:
side-channel-list: 1.0.0
side-channel-map: 1.0.1
side-channel-weakmap: 1.0.2
- dev: true
/signal-exit@3.0.7:
resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==}
@@ -16823,6 +17678,13 @@ packages:
dependencies:
is-arrayish: 0.3.2
+ /simple-update-notifier@2.0.0:
+ resolution: {integrity: sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==}
+ engines: {node: '>=10'}
+ dependencies:
+ semver: 7.6.3
+ dev: true
+
/slack@11.0.2:
resolution: {integrity: sha512-rv842+S+AGyZCmMMd8xPtW5DvJ9LzWTAKfxi8Gw57oYlXgcKtFuHd4nqk6lTPpRKdUGn3tx/Drd0rjQR3dQPqw==}
deprecated: this library is no longer maintained; if you are interested in taking this package on let us know
@@ -16860,7 +17722,6 @@ packages:
engines: {node: '>= 6.0.0', npm: '>= 3.0.0'}
requiresBuild: true
dev: false
- optional: true
/snake-case@2.1.0:
resolution: {integrity: sha512-FMR5YoPFwOLuh4rRz92dywJjyKYZNLpMn1R5ujVpIYkbA9p01fq8RMg0FkO4M+Yobt4MjHeLTJVm5xFFBHSV2Q==}
@@ -16929,6 +17790,17 @@ packages:
dev: false
optional: true
+ /socks-proxy-agent@8.0.5:
+ resolution: {integrity: sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw==}
+ engines: {node: '>= 14'}
+ dependencies:
+ agent-base: 7.1.3
+ debug: 4.4.0(supports-color@8.1.1)
+ socks: 2.8.3
+ transitivePeerDependencies:
+ - supports-color
+ dev: false
+
/socks@2.8.3:
resolution: {integrity: sha512-l5x7VUUWbjVFbafGLxPWkYsHIhEvmF85tbIeFZWc8ZPtoMyybuEhL7Jye/ooC4/d48FgOjSJXgsF/AJPYCW8Zw==}
engines: {node: '>= 10.0.0', npm: '>= 3.0.0'}
@@ -16937,7 +17809,6 @@ packages:
ip-address: 9.0.5
smart-buffer: 4.2.0
dev: false
- optional: true
/sol-digger@0.0.2:
resolution: {integrity: sha512-oqrw1E/X2WWYUYCzKDM5INDDH2nWOWos4p2Cw2OF52qoZcTDzlKMJQ5pJFXKOCADCg6KggBO5WYE/vNb+kJ0Hg==}
@@ -17014,14 +17885,13 @@ packages:
dependencies:
command-exists: 1.2.9
commander: 8.3.0
- follow-redirects: 1.15.9(debug@4.4.0)
+ follow-redirects: 1.15.6(debug@4.4.0)
js-sha3: 0.8.0
memorystream: 0.3.1
semver: 5.7.2
tmp: 0.0.33
transitivePeerDependencies:
- debug
- dev: true
/solhint-plugin-prettier@0.0.5(prettier-plugin-solidity@1.3.1)(prettier@2.8.8):
resolution: {integrity: sha512-7jmWcnVshIrO2FFinIvDQmhQpfpS2rRRn3RejiYgnjIE68xO2bvrYvjqVNfrio4xH9ghOqn83tKuTzLjEbmGIA==}
@@ -17067,20 +17937,20 @@ packages:
dependencies:
'@solidity-parser/parser': 0.16.2
ajv: 6.12.6
- antlr4: 4.13.2
+ antlr4: 4.13.1
ast-parents: 0.0.1
chalk: 4.1.2
commander: 10.0.1
cosmiconfig: 8.3.6(typescript@5.7.3)
fast-diff: 1.3.0
glob: 8.1.0
- ignore: 5.3.2
+ ignore: 5.3.1
js-yaml: 4.1.0
lodash: 4.17.21
pluralize: 8.0.0
- semver: 7.6.3
+ semver: 7.6.2
strip-ansi: 6.0.1
- table: 6.9.0
+ table: 6.8.2
text-table: 0.2.0
optionalDependencies:
prettier: 2.8.8
@@ -17229,7 +18099,6 @@ packages:
dependencies:
buffer-from: 1.1.2
source-map: 0.6.1
- dev: true
/source-map-url@0.4.1:
resolution: {integrity: sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==}
@@ -17253,7 +18122,10 @@ packages:
/source-map@0.6.1:
resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==}
engines: {node: '>=0.10.0'}
- dev: true
+
+ /spawn-command@0.0.2:
+ resolution: {integrity: sha512-zC8zGoGkmc8J9ndvml8Xksr1Amk9qBujgbF0JAIWO7kXr43w0h/0GJNM/Vustixu+YE8N/MTrQ7N31FvHUACxQ==}
+ dev: false
/spawn-sync@1.0.15:
resolution: {integrity: sha512-9DWBgrgYZzNghseho0JOuh+5fg9u6QWhAWa51QC7+U5rCheZ/j1DrEZnyE0RBBRqZ9uEXGPgSSM0nky6burpVw==}
@@ -17300,7 +18172,6 @@ packages:
resolution: {integrity: sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==}
requiresBuild: true
dev: false
- optional: true
/sqlite3@5.1.7(bluebird@3.7.2):
resolution: {integrity: sha512-GGIyOiFaG+TUra3JIfkI/zGP8yZYLPQ0pl1bH+ODjiX57sPhrLU5sQJn1y9bDKZUFYkX1crlrPfSYt0BKKdkog==}
@@ -17338,7 +18209,6 @@ packages:
jsbn: 0.1.1
safer-buffer: 2.1.2
tweetnacl: 0.14.5
- dev: true
/ssri@8.0.1:
resolution: {integrity: sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ==}
@@ -17361,7 +18231,6 @@ packages:
engines: {node: '>=6'}
dependencies:
type-fest: 0.7.1
- dev: true
/standard-as-callback@2.1.0:
resolution: {integrity: sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A==}
@@ -17411,7 +18280,6 @@ packages:
code-point-at: 1.1.0
is-fullwidth-code-point: 1.0.0
strip-ansi: 3.0.1
- dev: true
/string-width@2.1.1:
resolution: {integrity: sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==}
@@ -17419,7 +18287,6 @@ packages:
dependencies:
is-fullwidth-code-point: 2.0.0
strip-ansi: 4.0.0
- dev: true
/string-width@4.2.3:
resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==}
@@ -17507,14 +18374,12 @@ packages:
engines: {node: '>=0.10.0'}
dependencies:
ansi-regex: 2.1.1
- dev: true
/strip-ansi@4.0.0:
resolution: {integrity: sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==}
engines: {node: '>=4'}
dependencies:
ansi-regex: 3.0.1
- dev: true
/strip-ansi@6.0.1:
resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==}
@@ -17543,7 +18408,6 @@ packages:
/strip-eof@1.0.0:
resolution: {integrity: sha512-7FCwGGmx8mD5xQd3RPUvnSpUXHM3BWuzjtpD4TXsfcZ9EL4azvVVUscFYwD9nx8Kh+uCBC00XBtAykoMHwTh8Q==}
engines: {node: '>=0.10.0'}
- dev: true
/strip-hex-prefix@1.0.0:
resolution: {integrity: sha512-q8d4ue7JGEiVcypji1bALTos+0pWtyGlivAWyPuTkHzuTCJqrK9sWxYQZUq6Nq3cuyv3bm734IhHvHtGGURU6A==}
@@ -17556,6 +18420,12 @@ packages:
engines: {node: '>=4'}
dev: true
+ /strip-json-comments@1.0.4:
+ resolution: {integrity: sha512-AOPG8EBc5wAikaG1/7uFCNFJwnKOuQwFTpYBdTW6OvWHeZBQBrAA/amefHGrEiOnCPcLFZK6FUPtWVKpQVIRgg==}
+ engines: {node: '>=0.8.0'}
+ hasBin: true
+ dev: false
+
/strip-json-comments@2.0.1:
resolution: {integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==}
engines: {node: '>=0.10.0'}
@@ -17563,7 +18433,6 @@ packages:
/strip-json-comments@3.1.1:
resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==}
engines: {node: '>=8'}
- dev: true
/superstruct@0.15.5:
resolution: {integrity: sha512-4AOeU+P5UuE/4nOUkmcQdW5y7i9ndt1cQd/3iUe+LTz3RxESf/W/5lg4B74HbDMMv8PHnPnGCQFH45kBcrQYoQ==}
@@ -17633,6 +18502,37 @@ packages:
resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==}
engines: {node: '>= 0.4'}
+ /swagger-typescript-codegen@3.2.4:
+ resolution: {integrity: sha512-IEBRPd/Su5AggaHXtGsxJ3gyJU7k4QDb3UN5HziRMNK7ykZnJcwpvh55HOZpH5RBL2XW1DHJuNZs7P+2PUaUHw==}
+ hasBin: true
+ dependencies:
+ commander: 2.20.3
+ js-beautify: 1.15.1
+ jshint: 2.13.6
+ lodash: 4.17.21
+ mustache: 3.2.1
+ update-notifier: 4.1.3
+ dev: false
+
+ /swagger2openapi@5.4.0(ajv@6.12.6):
+ resolution: {integrity: sha512-f5QqfXawiVijhjMtYqWZ55ESHPZFqrPC8L9idhIiuSX8O2qsa1i4MVGtCM3TQF+Smzr/6WfT/7zBuzG3aTgPAA==}
+ hasBin: true
+ dependencies:
+ better-ajv-errors: 0.6.7(ajv@6.12.6)
+ call-me-maybe: 1.0.2
+ node-fetch-h2: 2.3.0
+ node-readfiles: 0.2.0
+ oas-kit-common: 1.0.8
+ oas-resolver: 2.5.6
+ oas-schema-walker: 1.1.5
+ oas-validator: 3.4.0
+ reftools: 1.1.9
+ yaml: 1.10.2
+ yargs: 12.0.5
+ transitivePeerDependencies:
+ - ajv
+ dev: false
+
/swap-case@1.1.2:
resolution: {integrity: sha512-BAmWG6/bx8syfc6qXPprof3Mn5vQgf5dwdUNJhsNqU9WdPt5P+ES/wQ5bxfijy8zwZgZZHslC3iAsxsuQMCzJQ==}
dependencies:
@@ -17696,17 +18596,6 @@ packages:
strip-ansi: 6.0.1
dev: true
- /table@6.9.0:
- resolution: {integrity: sha512-9kY+CygyYM6j02t5YFHbNz2FN5QmYGv9zAjVp4lCDjlCw7amdckXlEt/bjMhUIfj4ThGRE4gCUH5+yGnNuPo5A==}
- engines: {node: '>=10.0.0'}
- dependencies:
- ajv: 8.17.1
- lodash.truncate: 4.4.2
- slice-ansi: 4.0.0
- string-width: 4.2.3
- strip-ansi: 6.0.1
- dev: true
-
/tapable@2.2.1:
resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==}
engines: {node: '>=6'}
@@ -17793,6 +18682,11 @@ packages:
dependencies:
bintrees: 1.0.2
+ /term-size@2.2.1:
+ resolution: {integrity: sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==}
+ engines: {node: '>=8'}
+ dev: false
+
/test-value@2.1.0:
resolution: {integrity: sha512-+1epbAxtKeXttkGFMTX9H42oqzOTufR1ceCF+GYA5aOmvaPq9wd4PUS8329fn2RRLGNeUkgRLnVpycjx8DsO2w==}
engines: {node: '>=0.10.0'}
@@ -17880,7 +18774,6 @@ packages:
dependencies:
fdir: 6.4.3(picomatch@4.0.2)
picomatch: 4.0.2
- dev: true
/title-case@2.1.1:
resolution: {integrity: sha512-EkJoZ2O3zdCz3zJsYCsxyq2OC5hrxR9mfdd5I+w8h/tmFfeOxJ+vvkxsKxdmN0WtS9zLdHEgfgVOiMVgv+Po4Q==}
@@ -17894,7 +18787,6 @@ packages:
engines: {node: '>=0.6.0'}
dependencies:
os-tmpdir: 1.0.2
- dev: true
/tmp@0.1.0:
resolution: {integrity: sha512-J7Z2K08jbGcdA1kkQpJSqLF6T0tdQqpR2pnSUXsIchbPdTI9v3e85cLW0d6WDhwuAleOV71j2xWs8qMPfK7nKw==}
@@ -17923,7 +18815,6 @@ packages:
/to-readable-stream@1.0.0:
resolution: {integrity: sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==}
engines: {node: '>=6'}
- dev: true
/to-regex-range@2.1.1:
resolution: {integrity: sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==}
@@ -17938,7 +18829,6 @@ packages:
engines: {node: '>=8.0'}
dependencies:
is-number: 7.0.0
- dev: true
/to-regex@3.0.2:
resolution: {integrity: sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==}
@@ -17957,6 +18847,11 @@ packages:
/toml@3.0.0:
resolution: {integrity: sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w==}
+ /touch@3.1.1:
+ resolution: {integrity: sha512-r0eojU4bI8MnHr8c5bNo7lJDdI2qXlWWJk6a9EAFG7vbhTjElYhBVS3/miuE0uOuoLdb8Mc/rVfsmm6eo5o9GA==}
+ hasBin: true
+ dev: true
+
/tough-cookie@0.12.1:
resolution: {integrity: sha512-+gd4PklNJsxzu1NoNjhGRfOZZ5llND6VtQZGuaDXdmI0Ii79V5+YCa2sLx8Q6lYhYN2+9frCzUwOLQpuwHvO4Q==}
engines: {node: '>=0.4.12'}
@@ -17971,7 +18866,6 @@ packages:
dependencies:
psl: 1.9.0
punycode: 2.3.1
- dev: true
/tr46@0.0.3:
resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==}
@@ -17980,6 +18874,10 @@ packages:
resolution: {integrity: sha512-up6Yvai4PYKhpNp5PkYtx50m3KbwQrqDwbuZP/ItyL64YEWHAvH6Md83LFLV/GRSk/BoUVwwgUzX6SOQSbsfAg==}
dev: true
+ /tree-kill@1.2.2:
+ resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==}
+ hasBin: true
+
/trim-right@1.0.1:
resolution: {integrity: sha512-WZGXGstmCWgeevgTL54hrCuw1dyMQIzWy7ZfqRJfSmJZBwklI15egmQytFP6bPidmw3M8d5yEowl1niq4vmqZw==}
engines: {node: '>=0.10.0'}
@@ -18034,7 +18932,7 @@ packages:
engines: {node: '>=8'}
requiresBuild: true
dependencies:
- tslib: 2.6.3
+ tslib: 2.8.1
optional: true
/ts-node@10.9.2(@types/node@20.17.16)(typescript@5.7.3):
@@ -18066,6 +18964,38 @@ packages:
typescript: 5.7.3
v8-compile-cache-lib: 3.0.1
yn: 3.1.1
+ dev: true
+
+ /ts-node@10.9.2(@types/node@22.10.10)(typescript@5.7.3):
+ resolution: {integrity: sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==}
+ hasBin: true
+ peerDependencies:
+ '@swc/core': '>=1.2.50'
+ '@swc/wasm': '>=1.2.50'
+ '@types/node': '*'
+ typescript: '>=2.7'
+ peerDependenciesMeta:
+ '@swc/core':
+ optional: true
+ '@swc/wasm':
+ optional: true
+ dependencies:
+ '@cspotcode/source-map-support': 0.8.1
+ '@tsconfig/node10': 1.0.11
+ '@tsconfig/node12': 1.0.11
+ '@tsconfig/node14': 1.0.3
+ '@tsconfig/node16': 1.0.4
+ '@types/node': 22.10.10
+ acorn: 8.12.1
+ acorn-walk: 8.3.3
+ arg: 4.1.3
+ create-require: 1.1.1
+ diff: 4.0.2
+ make-error: 1.3.6
+ typescript: 5.7.3
+ v8-compile-cache-lib: 3.0.1
+ yn: 3.1.1
+ dev: false
/ts-node@8.10.2(typescript@5.7.3):
resolution: {integrity: sha512-ISJJGgkIpDdBhWVu3jufsWpK3Rzo7bdiIXJjQc0ynKxVOVcg2oIrf2H2cejminGrptVc6q6/uynAHNCuWGbpVA==}
@@ -18098,6 +19028,22 @@ packages:
yn: 3.1.1
dev: true
+ /ts-node@9.1.1(typescript@5.7.3):
+ resolution: {integrity: sha512-hPlt7ZACERQGf03M253ytLY3dHbGNGrAq9qIHWUY9XHYl1z7wYngSr3OQ5xmui8o2AaxsONxIzjafLUiWBo1Fg==}
+ engines: {node: '>=10.0.0'}
+ hasBin: true
+ peerDependencies:
+ typescript: '>=2.7'
+ dependencies:
+ arg: 4.1.3
+ create-require: 1.1.1
+ diff: 4.0.2
+ make-error: 1.3.6
+ source-map-support: 0.5.21
+ typescript: 5.7.3
+ yn: 3.1.1
+ dev: true
+
/ts-poet@6.9.0:
resolution: {integrity: sha512-roe6W6MeZmCjRmppyfOURklO5tQFQ6Sg7swURKkwYJvV7dbGCrK28um5+51iW3twdPRKtwarqFAVMU6G1mvnuQ==}
dependencies:
@@ -18129,7 +19075,6 @@ packages:
/tslib@1.14.1:
resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==}
- dev: true
/tslib@2.6.3:
resolution: {integrity: sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==}
@@ -18143,7 +19088,6 @@ packages:
/tsort@0.0.1:
resolution: {integrity: sha512-Tyrf5mxF8Ofs1tNoxA13lFeZ2Zrbd6cKbuH3V+MQ5sb6DtBj5FjrXVsRWT8YvNAQTqNoz66dz1WsbigI22aEnw==}
- dev: true
/tsscmp@1.0.6:
resolution: {integrity: sha512-LxhtAkPDTkVCMQjt2h6eBVY28KCjikZqZfMcC15YBeNjkgUpdCfBu5HoiOTDu86v6smE8yOjyEktJ8hlbANHQA==}
@@ -18180,7 +19124,6 @@ packages:
/tweetnacl@0.14.5:
resolution: {integrity: sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==}
- dev: true
/tweetnacl@1.0.3:
resolution: {integrity: sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==}
@@ -18212,17 +19155,19 @@ packages:
/type-fest@0.20.2:
resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==}
engines: {node: '>=10'}
- dev: true
/type-fest@0.21.3:
resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==}
engines: {node: '>=10'}
- dev: true
/type-fest@0.7.1:
resolution: {integrity: sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg==}
engines: {node: '>=8'}
- dev: true
+
+ /type-fest@0.8.1:
+ resolution: {integrity: sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==}
+ engines: {node: '>=8'}
+ dev: false
/type-fest@3.13.1:
resolution: {integrity: sha512-tLq3bSNx+xSpwvAJnzrK0Ep5CLNWjvFTOp71URMaAEWBfRb9nnJiBoUe0tF8bI4ZFO3omgBR6NvnbzVUT3Ly4g==}
@@ -18246,7 +19191,7 @@ packages:
hasBin: true
dependencies:
command-line-args: 4.0.7
- debug: 4.3.5
+ debug: 4.4.0(supports-color@8.1.1)
fs-extra: 7.0.1
js-sha3: 0.8.0
lodash: 4.17.21
@@ -18350,7 +19295,6 @@ packages:
resolution: {integrity: sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==}
dependencies:
is-typedarray: 1.0.0
- dev: true
/typedarray@0.0.6:
resolution: {integrity: sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==}
@@ -18420,6 +19364,13 @@ packages:
dev: true
optional: true
+ /uid@2.0.2:
+ resolution: {integrity: sha512-u3xV3X7uzvi5b1MncmZo3i2Aw222Zk1keqLA1YkHldREkAhAqi65wuPfe7lHx8H/Wzy+8CE7S7uS3jekIM5s8g==}
+ engines: {node: '>=8'}
+ dependencies:
+ '@lukeed/csprng': 1.1.0
+ dev: false
+
/ultron@1.1.1:
resolution: {integrity: sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og==}
dev: true
@@ -18443,6 +19394,10 @@ packages:
which-boxed-primitive: 1.1.1
dev: true
+ /undefsafe@2.0.5:
+ resolution: {integrity: sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==}
+ dev: true
+
/underscore@1.13.7:
resolution: {integrity: sha512-GMXzWtsc57XAtguZgaQViUOzs0KTkk8ojr3/xAxXLITqf/3EMwxC0inyETfDFjH/Krbhuep0HNbbjI9i/q3F3g==}
dev: true
@@ -18474,7 +19429,6 @@ packages:
engines: {node: '>=14.0'}
dependencies:
'@fastify/busboy': 2.1.1
- dev: true
/undici@6.21.1:
resolution: {integrity: sha512-q/1rj5D0/zayJB2FraXdaWxbhWiNKDvu8naDT2dl1yTlvJp4BLtOcp2a5BvgGNQpYYJzau7tf1WgKv3b+7mqpQ==}
@@ -18507,10 +19461,16 @@ packages:
dev: false
optional: true
+ /unique-string@2.0.0:
+ resolution: {integrity: sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==}
+ engines: {node: '>=8'}
+ dependencies:
+ crypto-random-string: 2.0.0
+ dev: false
+
/universalify@0.1.2:
resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==}
engines: {node: '>= 4.0.0'}
- dev: true
/universalify@2.0.1:
resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==}
@@ -18539,6 +19499,25 @@ packages:
requiresBuild: true
optional: true
+ /update-notifier@4.1.3:
+ resolution: {integrity: sha512-Yld6Z0RyCYGB6ckIjffGOSOmHXj1gMeE7aROz4MG+XMkmixBX4jUngrGXNYz7wPKBmtoD4MnBa2Anu7RSKht/A==}
+ engines: {node: '>=8'}
+ dependencies:
+ boxen: 4.2.0
+ chalk: 3.0.0
+ configstore: 5.0.1
+ has-yarn: 2.1.0
+ import-lazy: 2.1.0
+ is-ci: 2.0.0
+ is-installed-globally: 0.3.2
+ is-npm: 4.0.0
+ is-yarn-global: 0.3.0
+ latest-version: 5.1.0
+ pupa: 2.1.1
+ semver-diff: 3.1.1
+ xdg-basedir: 4.0.0
+ dev: false
+
/upper-case-first@1.1.2:
resolution: {integrity: sha512-wINKYvI3Db8dtjikdAqoBbZoP6Q+PZUyfMR7pmwHzjC2quzSkUq5DmPrTtPEqHaz8AGtmsB4TqwapMTM1QAQOQ==}
dependencies:
@@ -18553,7 +19532,6 @@ packages:
resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==}
dependencies:
punycode: 2.3.1
- dev: true
/urix@0.1.0:
resolution: {integrity: sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg==}
@@ -18569,7 +19547,6 @@ packages:
engines: {node: '>=4'}
dependencies:
prepend-http: 2.0.0
- dev: true
/url-set-query@1.0.0:
resolution: {integrity: sha512-3AChu4NiXquPfeckE5R5cGdiHCMWJx1dwCWOmWIL4KHAziJNOFIYJlpGFeKDvwLPHovZRCxK3cYlwzqI9Vp+Gg==}
@@ -18579,7 +19556,7 @@ packages:
resolution: {integrity: sha512-6hxOLGfZASQK/cijlZnZJTq8OXAkt/3YGfQX45vvMYXpZoo8NdWZcY73K108Jf759lS1Bv/8wXnHDTSz17dSRw==}
dependencies:
punycode: 1.4.1
- qs: 6.12.3
+ qs: 6.14.0
dev: true
/usb@1.9.2:
@@ -18665,7 +19642,6 @@ packages:
resolution: {integrity: sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==}
deprecated: Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.
hasBin: true
- dev: true
/uuid@8.3.2:
resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==}
@@ -18704,11 +19680,16 @@ packages:
assert-plus: 1.0.0
core-util-is: 1.0.2
extsprintf: 1.3.0
- dev: true
/vlq@2.0.4:
resolution: {integrity: sha512-aodjPa2wPQFkra1G8CzJBTHXhgk3EVSwxSWXNPr1fgdFLUb8kvLV1iEb6rFgasIsjP82HWI6dsb5Io26DDnasA==}
+ /wcwidth@1.0.1:
+ resolution: {integrity: sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==}
+ dependencies:
+ defaults: 1.0.4
+ dev: false
+
/web3-bzz@1.10.0:
resolution: {integrity: sha512-o9IR59io3pDUsXTsps5pO5hW1D5zBmg46iNc2t4j2DkaYHNdDLwk2IP9ukoM2wg47QILfPEJYzhTfkS/CcX0KA==}
engines: {node: '>=8.0.0'}
@@ -19999,7 +20980,6 @@ packages:
/which-module@2.0.1:
resolution: {integrity: sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==}
- dev: true
/which-pm-runs@1.1.0:
resolution: {integrity: sha512-n1brCuqClxfFfq/Rb0ICg9giSZqCS+pLtccdag6C2HyufBrh3fBOiy9nb6ggRMvWOVH5GrdJskj5iGTZNxd7SA==}
@@ -20043,7 +21023,6 @@ packages:
hasBin: true
dependencies:
isexe: 2.0.0
- dev: true
/which@2.0.2:
resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==}
@@ -20065,7 +21044,6 @@ packages:
engines: {node: '>=8'}
dependencies:
string-width: 4.2.3
- dev: true
/wif@2.0.6:
resolution: {integrity: sha512-HIanZn1zmduSF+BQhkE+YXIbEiH0xPr1012QbFEGB0xsKqJii0/SqJjyn8dFv6y36kOznMgMB+LGcbZTJ1xACQ==}
@@ -20144,7 +21122,6 @@ packages:
/workerpool@6.5.1:
resolution: {integrity: sha512-Fs4dNYcsdpYSAfVxhnl1L5zTksjvOJxtC5hzMNl+1t9B8hTJTdKDyZ5ju7ztgPy+ft9tBFXoOlDNiOT9WUXZlA==}
- dev: true
/wrap-ansi@2.1.0:
resolution: {integrity: sha512-vAaEaDM946gbNpH5pLVNR+vX2ht6n0Bt3GXwVB1AuAqZosOvHNF3P7wDnh8KLkSqgUh0uh77le7Owgoz+Z9XBw==}
@@ -20152,7 +21129,15 @@ packages:
dependencies:
string-width: 1.0.2
strip-ansi: 3.0.1
- dev: true
+
+ /wrap-ansi@6.2.0:
+ resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==}
+ engines: {node: '>=8'}
+ dependencies:
+ ansi-styles: 4.3.0
+ string-width: 4.2.3
+ strip-ansi: 6.0.1
+ dev: false
/wrap-ansi@7.0.0:
resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==}
@@ -20173,6 +21158,15 @@ packages:
/wrappy@1.0.2:
resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==}
+ /write-file-atomic@3.0.3:
+ resolution: {integrity: sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==}
+ dependencies:
+ imurmurhash: 0.1.4
+ is-typedarray: 1.0.0
+ signal-exit: 3.0.7
+ typedarray-to-buffer: 3.1.5
+ dev: false
+
/ws@3.3.3:
resolution: {integrity: sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==}
peerDependencies:
@@ -20261,6 +21255,11 @@ packages:
bufferutil: 4.0.9
utf-8-validate: 5.0.10
+ /xdg-basedir@4.0.0:
+ resolution: {integrity: sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==}
+ engines: {node: '>=8'}
+ dev: false
+
/xhr-request-promise@0.1.3:
resolution: {integrity: sha512-YUBytBsuwgitWtdRzXDDkWAXzhdGB8bYm0sSzMPZT7Z2MBjMSTHFsyCT1yCRATY+XC69DUrQraRAEgcoCRaIPg==}
dependencies:
@@ -20323,7 +21322,6 @@ packages:
/y18n@3.2.2:
resolution: {integrity: sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ==}
- dev: true
/y18n@5.0.8:
resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==}
@@ -20349,7 +21347,13 @@ packages:
/yaml@1.10.2:
resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==}
engines: {node: '>= 6'}
- dev: true
+
+ /yargs-parser@11.1.1:
+ resolution: {integrity: sha512-C6kB/WJDiaxONLJQnF8ccx9SEeoTTLek8RVbaOIsrAUS8VrBEXfmeSnCZxygc+XC2sNMBIwOOnfcxiynjHsVSQ==}
+ dependencies:
+ camelcase: 5.3.1
+ decamelize: 1.2.0
+ dev: false
/yargs-parser@2.4.1:
resolution: {integrity: sha512-9pIKIJhnI5tonzG6OnCFlz/yln8xHYcGl+pn3xR0Vzff0vzN1PbNRaelgfgRUwZ3s4i3jvxT9WhmUGL4whnasA==}
@@ -20380,7 +21384,6 @@ packages:
decamelize: 4.0.0
flat: 5.0.2
is-plain-obj: 2.1.0
- dev: true
/yargs@10.1.2:
resolution: {integrity: sha512-ivSoxqBGYOqQVruxD35+EyCFDYNEFL/Uo6FcOnz+9xZdZzK0Zzw4r4KhbrME1Oo2gOggwJod2MnsdamSG7H9ig==}
@@ -20399,6 +21402,23 @@ packages:
yargs-parser: 8.1.0
dev: true
+ /yargs@12.0.5:
+ resolution: {integrity: sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw==}
+ dependencies:
+ cliui: 4.1.0
+ decamelize: 1.2.0
+ find-up: 3.0.0
+ get-caller-file: 1.0.3
+ os-locale: 3.1.0
+ require-directory: 2.1.1
+ require-main-filename: 1.0.1
+ set-blocking: 2.0.0
+ string-width: 2.1.1
+ which-module: 2.0.1
+ y18n: 3.2.2
+ yargs-parser: 11.1.1
+ dev: false
+
/yargs@16.2.0:
resolution: {integrity: sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==}
engines: {node: '>=10'}
@@ -20453,7 +21473,6 @@ packages:
/yocto-queue@0.1.0:
resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
engines: {node: '>=10'}
- dev: true
/zen-observable-ts@1.2.5:
resolution: {integrity: sha512-QZWQekv6iB72Naeake9hS1KxHlotfRpe+WGNbNx5/ta+R3DNjVO2bswf63gXlWDcs+EMd7XY8HfVQyP1X6T4Zg==}
diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml
index 81effa6c94..b5396b3b2a 100644
--- a/pnpm-workspace.yaml
+++ b/pnpm-workspace.yaml
@@ -1,3 +1,4 @@
packages:
- 'packages/*'
- - 'lib/safe-contracts/'
\ No newline at end of file
+ - 'lib/safe-contracts/'
+ - 'helpers/wormholescanMock/'
\ No newline at end of file
diff --git a/scripts/check-recovery.js b/scripts/check-recovery.js
index c3bb09cf88..fca6818671 100755
--- a/scripts/check-recovery.js
+++ b/scripts/check-recovery.js
@@ -27,6 +27,8 @@ walkSync("./contracts/").forEach((contractName) => {
[
"contracts/bridging/IColonyBridge.sol",
"contracts/bridging/WormholeBridgeForColony.sol",
+ "contracts/bridging/ProxyColony.sol",
+ "contracts/bridging/ProxyColonyNetwork.sol",
"contracts/colony/ColonyAuthority.sol",
"contracts/colony/ColonyStorage.sol",
"contracts/colony/IColony.sol",
@@ -49,6 +51,8 @@ walkSync("./contracts/").forEach((contractName) => {
"contracts/common/Multicall.sol",
"contracts/common/Resolver.sol",
"contracts/common/TokenAuthority.sol", // Imported from colonyToken repo
+ "contracts/common/DomainReceiverManagement.sol", // Is used, but in multiple places and has its own implementation for now
+ "contracts/common/DomainTokenReceiver.sol",
"contracts/ens/ENS.sol",
"contracts/ens/ENSRegistry.sol",
"contracts/extensions/IColonyExtension.sol",
@@ -91,6 +95,7 @@ walkSync("./contracts/").forEach((contractName) => {
"contracts/testHelpers/ERC721Mock.sol",
"contracts/testHelpers/NoLimitSubdomains.sol",
"contracts/testHelpers/GasGuzzler.sol",
+ "contracts/testHelpers/LiFiFacetProxyMock.sol",
"contracts/testHelpers/TasksPayments.sol",
"contracts/testHelpers/ToggleableToken.sol",
"contracts/testHelpers/FunctionsNotAvailableOnColony.sol",
diff --git a/scripts/check-storage.js b/scripts/check-storage.js
index bf0056bebf..23101b7170 100755
--- a/scripts/check-storage.js
+++ b/scripts/check-storage.js
@@ -17,6 +17,8 @@ walkSync("./contracts/").forEach((contractName) => {
if (
[
"contracts/bridging/WormholeBridgeForColony.sol",
+ "contracts/bridging/ProxyColony.sol",
+ "contracts/bridging/ProxyColonyNetwork.sol",
"contracts/colony/ColonyAuthority.sol",
"contracts/colony/ColonyStorage.sol",
"contracts/colonyNetwork/ColonyNetworkAuthority.sol",
diff --git a/scripts/mockGuardianSpy.ts b/scripts/mockGuardianSpy.ts
index 2cd06daf50..b205d33170 100644
--- a/scripts/mockGuardianSpy.ts
+++ b/scripts/mockGuardianSpy.ts
@@ -1,67 +1,69 @@
-/* eslint-disable import/no-extraneous-dependencies */
-
import { Server, ServerCredentials } from "@grpc/grpc-js";
-import { ServerWritableStreamImpl } from "@grpc/grpc-js/build/src/server-call";
-
-import { ethers } from "ethers";
-import { RetryProvider } from "../packages/package-utils";
+import { Contract, Signer, ContractReceipt, ethers } from "ethers";
+import { ServerWritableStreamImpl } from "@grpc/grpc-js/build/src/server-call";
import {
FilterEntry,
SpyRPCServiceService,
SubscribeSignedVAARequest,
SubscribeSignedVAAResponse,
} from "../lib/wormhole/sdk/js-proto-node/src/spy/v1/spy";
-import { evmChainIdToWormholeChainId } from "../helpers/test-helper";
+// const { RetryProvider } = require("../packages/package-utils");
+import { RetryProvider } from "../packages/package-utils";
// Random key
+// eslint-disable-next-line import/no-unresolved
import { abi as bridgeAbi } from "../artifacts/contracts/testHelpers/WormholeMock.sol/WormholeMock.json";
+// eslint-disable-next-line import/no-unresolved
import { abi as wormholeBridgeForColonyAbi } from "../artifacts/contracts/bridging/WormholeBridgeForColony.sol/WormholeBridgeForColony.json";
+import encodeMockVAA from "../helpers/wormholescanMock/src/encodeMockVAA";
+
function ethereumAddressToWormholeAddress(address: string) {
return ethers.utils.hexZeroPad(ethers.utils.hexStripZeros(ethers.utils.hexlify(address)), 32);
}
-type QueueEntry = [ethers.Contract, string, number, number, string, number, number];
+type QueueEntry = [Contract, string, number, number, string, number, number];
class MockGuardianSpy {
homeRpc: string;
- foreignRpc: string;
+ foreignRpcs: string[];
homeBridgeAddress: string;
- foreignBridgeAddress: string;
+ foreignBridgeAddresses: string[];
homeColonyBridgeAddress: string;
- foreignColonyBridgeAddress: string;
+ foreignColonyBridgeAddresses: string[];
+
+ spyWaitsForBridgedTransaction: boolean;
- homeBridge: ethers.Contract;
+ homeBridge: Contract;
- foreignBridge: ethers.Contract;
+ foreignBridges: Contract[];
- homeWormholeBridgeForColony: ethers.Contract;
+ homeWormholeBridgeForColony: Contract;
- foreignWormholeBridgeForColony: ethers.Contract;
+ foreignWormholeBridgesForColony: Contract[];
- skipCount = 0;
+ skipCount: number = 0;
queue: QueueEntry[] = [];
skipped: QueueEntry[] = [];
- locked = false;
-
- bridgingPromiseCount = 0;
+ locked: boolean = false;
- resolveBridgingPromise: (tx: ethers.Transaction) => void;
+ bridgingPromiseCount: number = 0;
- signerHome: ethers.Signer;
+ resolveBridgingPromise: (tx: ContractReceipt) => void;
- signerForeign: ethers.Signer;
+ signerHome: Signer;
+ // signerForeign: any;
server: Server;
subscription: ServerWritableStreamImpl;
@@ -80,21 +82,24 @@ class MockGuardianSpy {
* @param {string} foreignBridgeAddress The address of the foreign bridge contract
* @param {string} homeColonyBridgeAddress The address of the home colony bridge contract
* @param {string} foreignColonyBridgeAddress The address of the foreign colony bridge contract
+ * @param {string} spyWaitsForBridgedTransaction Whether the spy waits for the bridging transaction to be mined
*/
constructor(
homeRpc: string,
- foreignRpc: string,
+ foreignRpcs: string[],
homeBridgeAddress: string,
- foreignBridgeAddress: string,
+ foreignBridgeAddresses: string[],
homeColonyBridgeAddress: string,
- foreignColonyBridgeAddress: string,
+ foreignColonyBridgeAddresses: string[],
+ spyWaitsForBridgedTransaction: boolean,
) {
this.homeRpc = homeRpc;
- this.foreignRpc = foreignRpc;
+ this.foreignRpcs = foreignRpcs;
this.homeBridgeAddress = homeBridgeAddress;
- this.foreignBridgeAddress = foreignBridgeAddress;
+ this.foreignBridgeAddresses = foreignBridgeAddresses;
this.homeColonyBridgeAddress = homeColonyBridgeAddress;
- this.foreignColonyBridgeAddress = foreignColonyBridgeAddress;
+ this.foreignColonyBridgeAddresses = foreignColonyBridgeAddresses;
+ this.spyWaitsForBridgedTransaction = spyWaitsForBridgedTransaction;
this.setupListeners();
@@ -124,7 +129,7 @@ class MockGuardianSpy {
});
}
- static async getTransactionFromAddressWithNonce(provider: ethers.providers.Provider, address: string, nonce: number) {
+ static async getTransactionFromAddressWithNonce(provider: Contract["provider"], address: string, nonce: number) {
const currentBlock = await provider.getBlockNumber();
for (let i = currentBlock; i > 0; i -= 1) {
const block = await provider.getBlock(i);
@@ -143,99 +148,120 @@ class MockGuardianSpy {
// Note that the documentation sometimes also calls them VMs (as does IWormhole)
// I believe VM stands for 'Verified Message'
async encodeMockVAA(sender: string, sequence: number, nonce: number, payload: string, consistencyLevel: number, chainId: number) {
- const timestamp = Math.floor(Date.now() / 1000);
- const emitterChainId = chainId;
- const emitterAddress = ethereumAddressToWormholeAddress(sender);
-
- // const vaa = await this.homeBridge.buildVM(
- // version,
- // timestamp,
- // nonce,
- // emitterChainId,
- // emitterAddress,
- // sequence.toString(),
- // consistencyLevel,
- // payload,
- // guardianSetIndex,
- // signatures,
- // hash,
- // );
-
- // Build the VAA body
- const vaaBody = await this.homeBridge.buildVAABody(timestamp, nonce, emitterChainId, emitterAddress, sequence, consistencyLevel, payload);
-
- // const signatures = guardians.addSignatures(vaaBody, [0]);
- // Build the VAA header
-
- const vaaHeader =
- "0x01" + // version
- "00000000" + // guardianSetIndex
- "01" + // signature count
- "01" + // signature index
- "7777000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007777";
-
- return vaaHeader + vaaBody.toString("hex").slice(2);
+ return encodeMockVAA(sender, sequence, nonce, payload, consistencyLevel, chainId, this.homeBridge.address, this.homeBridge.provider);
+ }
+
+ setupForeignBridges(foreignRpc, foreignBridgeAddress, foreignColonyBridgeAddress) {
+ const signerForeign = new RetryProvider(foreignRpc).getSigner();
+ const foreignBridge = new ethers.Contract(foreignBridgeAddress, bridgeAbi, signerForeign);
+ const foreignWormholeBridgeForColony = new ethers.Contract(foreignColonyBridgeAddress, wormholeBridgeForColonyAbi, signerForeign);
+
+ this.foreignBridges.push(foreignBridge);
+ this.foreignWormholeBridgesForColony.push(foreignWormholeBridgeForColony);
+ }
+
+ async getColonyBridgeWithChainId(chainId) {
+ if ((await this.homeBridge.provider.getNetwork()).chainId === chainId) {
+ return this.homeBridge;
+ }
+ for (const foreignBridge of this.foreignWormholeBridgesForColony) {
+ if ((await foreignBridge.provider.getNetwork()).chainId === chainId) {
+ return foreignBridge;
+ }
+ }
+ throw new Error("No bridge found for chainId");
+ }
+
+ static getWormholeChainId(chainId) {
+ // Due to limitations, for local testing, our wormhole chainIDs have to be 'real' wormhole chainids.
+ // So I've decreed that for chainId 256669100, we use 10003 (which is really arbitrum sepolia)
+ // and for chainId 256669101, we use 10002 (which is really sepolia).
+ // This isn't ideal, but it's the best solution I have for now
+ if (chainId === 265669100) {
+ return 10003;
+ }
+ if (chainId === 265669101) {
+ return 10002;
+ }
+ if (chainId === 265669102) {
+ return 10005;
+ }
+ throw new Error("Unsupported chainId");
}
setupListeners() {
if (this.homeBridge) {
this.homeBridge.removeAllListeners("LogMessagePublished");
}
- if (this.foreignBridge) {
- this.foreignBridge.removeAllListeners("LogMessagePublished");
+ if (this.foreignBridges && this.foreignBridges.length > 0) {
+ for (const bridge of this.foreignBridges) {
+ bridge.removeAllListeners("LogMessagePublished");
+ }
}
- this.signerHome = new RetryProvider(this.homeRpc).getSigner();
- this.signerForeign = new RetryProvider(this.foreignRpc).getSigner();
+ this.foreignBridges = [];
+ this.foreignWormholeBridgesForColony = [];
+ this.signerHome = new RetryProvider(this.homeRpc).getSigner();
+ // this.signerForeign = new RetryProvider(this.foreignRpc).getSigner();
this.homeBridge = new ethers.Contract(this.homeBridgeAddress, bridgeAbi, this.signerHome);
- this.foreignBridge = new ethers.Contract(this.foreignBridgeAddress, bridgeAbi, this.signerForeign);
+ // this.foreignBridge = new ethers.Contract(this.foreignBridgeAddress, bridgeAbi, this.signerForeign);
this.homeWormholeBridgeForColony = new ethers.Contract(this.homeColonyBridgeAddress, wormholeBridgeForColonyAbi, this.signerHome);
- this.foreignWormholeBridgeForColony = new ethers.Contract(this.foreignColonyBridgeAddress, wormholeBridgeForColonyAbi, this.signerForeign);
-
+ // this.foreignWormholeBridgeForColony = new ethers.Contract(this.foreignColonyBridgeAddress, wormholeBridgeForColonyAbi, this.signerForeign);
+ for (let i = 0; i < this.foreignRpcs.length; i += 1) {
+ this.setupForeignBridges(this.foreignRpcs[i], this.foreignBridgeAddresses[i], this.foreignColonyBridgeAddresses[i]);
+ }
this.skipCount = 0;
this.queue = [];
this.skipped = [];
this.locked = false;
this.homeBridge.on("LogMessagePublished", async (sender, sequence, nonce, payload, consistencyLevel) => {
- const { chainId } = await this.signerHome.provider.getNetwork();
- // Due to limitations, for local testing, our wormhole chainIDs have to be 'real' wormhole chainids.
- // So I've decreed that for chainId 256669100, we use 10003 (which is really arbitrum sepolia)
- // and for chainId 256669101, we use 10002 (which is really sepolia).
- // This isn't ideal, but it's the best solution I have for now
- const wormholeChainId = evmChainIdToWormholeChainId(chainId);
-
- if (this.skipCount > 0) {
- this.skipped.push([this.foreignWormholeBridgeForColony, sender, sequence, nonce, payload, consistencyLevel, wormholeChainId]);
- this.skipCount -= 1;
- return;
+ try {
+ const { chainId } = await this.signerHome.provider.getNetwork();
+ const [destinationEvmChainId] = new ethers.utils.AbiCoder().decode(["uint256", "address", "bytes"], `${payload.toString("hex")}`);
+
+ const destinationBridge = await this.getColonyBridgeWithChainId(destinationEvmChainId.toNumber());
+ const wormholeChainId = MockGuardianSpy.getWormholeChainId(chainId);
+
+ if (this.skipCount > 0) {
+ this.skipped.push([destinationBridge, sender, sequence, nonce, payload, consistencyLevel, wormholeChainId]);
+ this.skipCount -= 1;
+ return;
+ }
+ this.queue.push([destinationBridge, sender, sequence, nonce, payload, consistencyLevel, wormholeChainId]);
+ await this.processQueue();
+ } catch (e) {
+ console.log("Error in LogMessagePublished listener");
+ console.log(e);
}
- this.queue.push([this.foreignWormholeBridgeForColony, sender, sequence, nonce, payload, consistencyLevel, wormholeChainId]);
- await this.processQueue();
});
- this.foreignBridge.on("LogMessagePublished", async (sender, sequence, nonce, payload, consistencyLevel) => {
- const { chainId } = await this.signerForeign.provider.getNetwork();
- // Due to limitations, for local testing, our wormhole chainIDs have to be 'real' wormhole chainids.
- // So I've decreed that for chainId 256669100, we use 10003 (which is really arbitrum sepolia)
- // and for chainId 256669101, we use 10002 (which is really sepolia).
- // This isn't ideal, but it's the best solution I have for now
- const wormholeChainId = evmChainIdToWormholeChainId(chainId);
-
- if (this.skipCount > 0) {
- this.skipped.push([this.homeWormholeBridgeForColony, sender, sequence, nonce, payload, consistencyLevel, wormholeChainId]);
- this.skipCount -= 1;
- return;
- }
- this.queue.push([this.homeWormholeBridgeForColony, sender, sequence, nonce, payload, consistencyLevel, wormholeChainId]);
+ for (const foreignBridge of this.foreignBridges) {
+ foreignBridge.on("LogMessagePublished", async (sender, sequence, nonce, payload, consistencyLevel) => {
+ const { chainId } = await foreignBridge.provider.getNetwork();
+ const [destinationEvmChainId] = new ethers.utils.AbiCoder().decode(["uint256", "address", "bytes"], `${payload.toString("hex")}`);
- await this.processQueue();
- });
+ if (destinationEvmChainId.toNumber() !== 265669100) {
+ throw new Error("Unsupported chainId - change assumptions in mockGuardianSpy.ts");
+ }
+
+ const wormholeChainId = MockGuardianSpy.getWormholeChainId(chainId);
+
+ if (this.skipCount > 0) {
+ this.skipped.push([this.homeWormholeBridgeForColony, sender, sequence, nonce, payload, consistencyLevel, wormholeChainId]);
+ this.skipCount -= 1;
+ return;
+ }
+ this.queue.push([this.homeWormholeBridgeForColony, sender, sequence, nonce, payload, consistencyLevel, wormholeChainId]);
+
+ await this.processQueue();
+ });
+ }
console.log("Mock Bridge Monitor running");
console.log("Home bridge address: ", this.homeBridgeAddress);
- console.log("Foreign bridge address: ", this.foreignBridgeAddress);
+ console.log("Foreign bridge addresses: ", this.foreignBridgeAddresses);
}
close() {} // eslint-disable-line class-methods-use-this
@@ -266,18 +292,22 @@ class MockGuardianSpy {
const relayerNonce = await bridge.provider.getTransactionCount(this.relayerAddress, "pending");
this.subscription.write({ vaaBytes: Buffer.from(vaa.slice(2), "hex") });
- let newRelayerNonce = -1;
- while (newRelayerNonce <= relayerNonce) {
- newRelayerNonce = await bridge.provider.getTransactionCount(this.relayerAddress, "pending");
- }
+ if (this.spyWaitsForBridgedTransaction) {
+ let newRelayerNonce = -1;
+ while (newRelayerNonce <= relayerNonce) {
+ newRelayerNonce = await bridge.provider.getTransactionCount(this.relayerAddress, "pending");
+ }
- tx = await MockGuardianSpy.getTransactionFromAddressWithNonce(bridge.provider, this.relayerAddress, relayerNonce);
+ tx = await MockGuardianSpy.getTransactionFromAddressWithNonce(bridge.provider, this.relayerAddress, relayerNonce);
+ }
+ } else {
+ console.log("not sending, didnt pass filter");
}
this.bridgingPromiseCount -= 1;
-
if (this.bridgingPromiseCount === 0) {
- this.resolveBridgingPromise(tx);
+ const receipt = await bridge.provider.getTransactionReceipt(tx.hash);
+ this.resolveBridgingPromise(receipt);
}
if (this.locked) {
this.locked = false;
@@ -304,13 +334,14 @@ class MockGuardianSpy {
const relayerNonce = await bridge.provider.getTransactionCount(this.relayerAddress, "pending");
this.subscription.write({ vaaBytes: Buffer.from(vaa.slice(2), "hex") });
+ if (this.spyWaitsForBridgedTransaction) {
+ let newRelayerNonce = -1;
+ while (newRelayerNonce <= relayerNonce) {
+ newRelayerNonce = await bridge.provider.getTransactionCount(this.relayerAddress, "pending");
+ }
- let newRelayerNonce = -1;
- while (newRelayerNonce <= relayerNonce) {
- newRelayerNonce = await bridge.provider.getTransactionCount(this.relayerAddress, "pending");
+ tx = await MockGuardianSpy.getTransactionFromAddressWithNonce(bridge.provider, this.relayerAddress, relayerNonce);
}
-
- tx = await MockGuardianSpy.getTransactionFromAddressWithNonce(bridge.provider, this.relayerAddress, relayerNonce);
}
this.bridgingPromiseCount -= 1;
diff --git a/scripts/setup-bridging-contracts.js b/scripts/setup-bridging-contracts.js
index b134ff1ab9..6d9f9a6be5 100644
--- a/scripts/setup-bridging-contracts.js
+++ b/scripts/setup-bridging-contracts.js
@@ -10,7 +10,7 @@ const fs = require("fs");
const ethers = require("ethers"); // eslint-disable-line
const { spawn } = require("child_process");
const { TruffleLoader } = require("../packages/package-utils");
-const { WAD } = require("../helpers/constants");
+const { WAD, NETWORK_ADDRESS } = require("../helpers/constants");
const loader = new TruffleLoader({
contractRoot: path.resolve(__dirname, "..", `artifacts${process.env.SOLIDITY_COVERAGE ? "-coverage" : ""}`, "contracts"),
@@ -19,18 +19,22 @@ const loader = new TruffleLoader({
const ADDRESS_ZERO = ethers.constants.AddressZero;
const MockGuardianSpy = require("./mockGuardianSpy").default;
-async function setupBridging(homeRpcUrl, foreignRpcUrl) {
+async function setupBridging(homeRpcUrl, foreignRpcUrls, spyWaitsForBridgedTransaction) {
console.log("setup-bridging-contracts: Not to be used in production");
if (process.env.NODE_ENV === "production") {
process.exit(1);
}
-
- const ethersForeignProvider = new ethers.providers.StaticJsonRpcProvider(foreignRpcUrl);
- const ethersForeignSigner = ethersForeignProvider.getSigner();
+ const ethersForeignProviders = foreignRpcUrls.map((foreignRpcUrl) => new ethers.providers.StaticJsonRpcProvider(foreignRpcUrl));
+ // const ethersForeignProvider = new ethers.providers.StaticJsonRpcProvider(foreignRpcUrl);
+ const ethersForeignSigners = ethersForeignProviders.map((provider) => provider.getSigner());
+ // const ethersForeignSigner = ethersForeignProvider.getSigner();
const ethersHomeProvider = new ethers.providers.StaticJsonRpcProvider(homeRpcUrl);
const ethersHomeSigner = ethersHomeProvider.getSigner();
+ const homeChainId = (await ethersHomeSigner.provider.getNetwork()).chainId;
+ const foreignChainIds = await Promise.all(ethersForeignProviders.map((provider) => provider.getNetwork().then((network) => network.chainId)));
+ // const foreignChainId = (await ethersForeignSigner.provider.getNetwork()).chainId;
- const accounts = await ethersForeignProvider.listAccounts();
+ const accounts = await ethersHomeProvider.listAccounts();
let contractDir;
contractDir = path.resolve(__dirname, "..", "artifacts", "lib", "safe-contracts", "contracts");
@@ -46,100 +50,131 @@ async function setupBridging(homeRpcUrl, foreignRpcUrl) {
contractDir = path.resolve(__dirname, "..", "artifacts", "colonyToken");
const Token = await loader.load({ contractDir, contractName: "Token" });
- // This is the address that the gnosis safe proxy factory should have been deployed to by the deploy command using hardhat in their repo
- const gspf = new ethers.Contract("0xa6B71E26C5e0845f74c812102Ca7114b6a896AB2", GnosisSafeProxyFactory.abi, ethersForeignSigner);
-
- // 0xd9Db270c1B5E3Bd161E8c8503c55cEABeE709552 is the address the gnosis safe implementation should have been deployed at
- let receipt = await gspf.createProxy("0xd9Db270c1B5E3Bd161E8c8503c55cEABeE709552", "0x");
- let tx = await receipt.wait();
-
- const safeAddress = tx.events[0].args.proxy;
- const gnosisSafe = new ethers.Contract(safeAddress, GnosisSafe.abi, ethersForeignSigner);
- console.log("Gnosis Safe address: ", gnosisSafe.address);
-
- receipt = await gnosisSafe.setup([accounts[0]], 1, ADDRESS_ZERO, "0x", ADDRESS_ZERO, ADDRESS_ZERO, 0, ADDRESS_ZERO);
- await receipt.wait();
-
- const zodiacBridgeFactory = new ethers.ContractFactory(ZodiacBridgeModuleMock.abi, ZodiacBridgeModuleMock.bytecode, ethersForeignSigner);
- const zodiacBridge = await zodiacBridgeFactory.deploy(safeAddress);
- await zodiacBridge.deployTransaction.wait();
- console.log("Bridge module address: ", zodiacBridge.address);
-
- const erc721MockFactory = new ethers.ContractFactory(Erc721Mock.abi, Erc721Mock.bytecode, ethersForeignSigner);
- const erc721 = await erc721MockFactory.deploy();
- await erc721.deployTransaction.wait();
- console.log("ERC721 address: ", erc721.address);
-
- const tokenId = 1;
- const mintTx = await erc721.mint(gnosisSafe.address, tokenId);
- await mintTx.wait();
- const inventory = await erc721.balanceOf(gnosisSafe.address);
+ const foreignBridgeAddresses = [];
+ const remoteColonyBridgeAddresses = [];
+ const foreignBridges = [];
+ const remoteColonyBridges = [];
+ const gnosisSafes = [];
+ const zodiacBridges = [];
+
+ // eslint-disable-next-line no-restricted-syntax
+ for (const ethersForeignSigner of ethersForeignSigners) {
+ // This is the address that the gnosis safe proxy factory should have been deployed to by the deploy command using hardhat in their repo
+ const gspf = new ethers.Contract("0xa6B71E26C5e0845f74c812102Ca7114b6a896AB2", GnosisSafeProxyFactory.abi, ethersForeignSigner);
+
+ // 0xd9Db270c1B5E3Bd161E8c8503c55cEABeE709552 is the address the gnosis safe implementation should have been deployed at
+ let receipt = await gspf.createProxy("0xd9Db270c1B5E3Bd161E8c8503c55cEABeE709552", "0x");
+ let tx = await receipt.wait();
+
+ const safeAddress = tx.events[0].args.proxy;
+ const gnosisSafe = new ethers.Contract(safeAddress, GnosisSafe.abi, ethersForeignSigner);
+ console.log("Gnosis Safe address: ", gnosisSafe.address);
+
+ receipt = await gnosisSafe.setup([accounts[0]], 1, ADDRESS_ZERO, "0x", ADDRESS_ZERO, ADDRESS_ZERO, 0, ADDRESS_ZERO);
+ await receipt.wait();
+
+ const zodiacBridgeFactory = new ethers.ContractFactory(ZodiacBridgeModuleMock.abi, ZodiacBridgeModuleMock.bytecode, ethersForeignSigner);
+ const zodiacBridge = await zodiacBridgeFactory.deploy(safeAddress);
+ await zodiacBridge.deployTransaction.wait();
+ console.log("Bridge module address: ", zodiacBridge.address);
+
+ const erc721MockFactory = new ethers.ContractFactory(Erc721Mock.abi, Erc721Mock.bytecode, ethersForeignSigner);
+ const erc721 = await erc721MockFactory.deploy();
+ await erc721.deployTransaction.wait();
+ console.log("ERC721 address: ", erc721.address);
+
+ const tokenId = 1;
+ const mintTx = await erc721.mint(gnosisSafe.address, tokenId);
+ await mintTx.wait();
+ const inventory = await erc721.balanceOf(gnosisSafe.address);
+
+ console.log(`Safe ${gnosisSafe.address} contains ${inventory} NFT.`); // Should eq 1.
+ if (inventory.toString() !== "1") {
+ console.log("Safe did not contain exactly 1 NFT");
+ process.exit();
+ }
- console.log(`Safe ${gnosisSafe.address} contains ${inventory} NFT.`); // Should eq 1.
- if (inventory.toString() !== "1") {
- console.log("Safe did not contain exactly 1 NFT");
- process.exit();
- }
+ const TokenFactory = new ethers.ContractFactory(Token.abi, Token.bytecode, ethersForeignSigner);
+ const token = await TokenFactory.deploy("Test", "TST", 18);
+ await token.deployTransaction.wait();
+ console.log("Token address: ", Token.address);
- const TokenFactory = new ethers.ContractFactory(Token.abi, Token.bytecode, ethersForeignSigner);
- const token = await TokenFactory.deploy("Test", "TST", 18);
- await token.deployTransaction.wait();
- console.log("Token address: ", Token.address);
+ await token.unlock();
+ const mintTokensTx = await token["mint(address,uint256)"](gnosisSafe.address, WAD.muln(100).toString());
+ await mintTokensTx.wait();
+ const safeBalance = await token.balanceOf(gnosisSafe.address);
- await token.unlock();
- const mintTokensTx = await token["mint(address,uint256)"](gnosisSafe.address, WAD.muln(100).toString());
- await mintTokensTx.wait();
- const safeBalance = await token.balanceOf(gnosisSafe.address);
+ console.log(`Safe ${gnosisSafe.address} contains ${safeBalance} tokens.`); // Should eq 100000000000000000000.
+ if (safeBalance.toString() !== "100000000000000000000") {
+ console.log("Safe did not contain exactly 100000000000000000000 tokens after minting");
+ process.exit();
+ }
- console.log(`Safe ${gnosisSafe.address} contains ${safeBalance} tokens.`); // Should eq 100000000000000000000.
- if (safeBalance.toString() !== "100000000000000000000") {
- console.log("Safe did not contain exactly 100000000000000000000 tokens after minting");
- process.exit();
- }
+ // Add bridge module to safe
- // Add bridge module to safe
+ const nonce = await gnosisSafe.nonce();
- const nonce = await gnosisSafe.nonce();
+ const data = gnosisSafe.interface.encodeFunctionData("enableModule(address)", [zodiacBridge.address]);
+ const safeTxArgs = [safeAddress, 0, data, 0, 100000, 100000, 0, ADDRESS_ZERO, ADDRESS_ZERO, nonce];
+ const safeData = await gnosisSafe.encodeTransactionData(...safeTxArgs);
+ const safeDataHash = await gnosisSafe.getTransactionHash(...safeTxArgs);
- const data = gnosisSafe.interface.encodeFunctionData("enableModule(address)", [zodiacBridge.address]);
- const safeTxArgs = [safeAddress, 0, data, 0, 100000, 100000, 0, ADDRESS_ZERO, ADDRESS_ZERO, nonce];
- const safeData = await gnosisSafe.encodeTransactionData(...safeTxArgs);
- const safeDataHash = await gnosisSafe.getTransactionHash(...safeTxArgs);
+ const sig = await getSig(ethersForeignSigner.provider, accounts[0], safeDataHash);
- const sig = await getSig(ethersForeignProvider, accounts[0], safeDataHash);
+ await gnosisSafe.checkNSignatures(safeDataHash, safeData, sig, 1);
- await gnosisSafe.checkNSignatures(safeDataHash, safeData, sig, 1);
+ tx = await gnosisSafe.execTransaction(...safeTxArgs.slice(0, -1), sig);
- tx = await gnosisSafe.execTransaction(...safeTxArgs.slice(0, -1), sig);
+ const enabled = await gnosisSafe.isModuleEnabled(zodiacBridge.address);
- const enabled = await gnosisSafe.isModuleEnabled(zodiacBridge.address);
+ if (!enabled) {
+ console.log("Gnosis safe did not have bridge module enabled, exiting");
+ process.exit(1);
+ }
- if (!enabled) {
- console.log("Gnosis safe did not have bridge module enabled, exiting");
- process.exit(1);
+ // Deploy a foreign bridge
+ const [foreignBridge, remoteColonyBridge] = await deployBridge(ethersForeignSigner);
+ const foreignChainId = (await ethersForeignSigner.provider.getNetwork()).chainId;
+
+ foreignBridgeAddresses.push(foreignBridge.address);
+ remoteColonyBridgeAddresses.push(remoteColonyBridge.address);
+
+ console.log(`On chain ${foreignChainId}:`);
+ console.log(`foreign bridge address: ${foreignBridge.address}`);
+ console.log(`foreign colony bridge address: ${remoteColonyBridge.address}`);
+ console.log(`foreign rpc url: ${foreignRpcUrls[0]}`);
+ console.log(`gnosis safe address: ${gnosisSafe.address}`);
+ console.log(`zodiac bridge module address: ${zodiacBridge.address}`);
+ console.log(`erc721 address: ${erc721.address}`);
+ console.log(`token address: ${token.address}`);
+
+ foreignBridges.push(foreignBridge);
+ remoteColonyBridges.push(remoteColonyBridge);
+ gnosisSafes.push(gnosisSafe);
+ zodiacBridges.push(zodiacBridge);
}
- // Deploy a foreign bridge
- const [foreignBridge, foreignColonyBridge] = await deployBridge(ethersForeignSigner);
-
// Deploy a home bridge
const [homeBridge, homeColonyBridge] = await deployBridge(ethersHomeSigner);
// Start the bridge service
console.log(`Home RPC Url: ${homeRpcUrl}`);
- console.log(`Foreign RPC Url: ${foreignRpcUrl}`);
+ // console.log(`Foreign RPC Url: ${foreignRpcUrl}`);
const guardianSpy = new MockGuardianSpy(
homeRpcUrl,
- foreignRpcUrl,
+ foreignRpcUrls,
homeBridge.address,
- foreignBridge.address,
+ foreignBridgeAddresses,
homeColonyBridge.address,
- foreignColonyBridge.address,
+ remoteColonyBridgeAddresses,
+ spyWaitsForBridgedTransaction,
); // eslint-disable-line no-unused-vars
// TODO: Start the bridge monitor
console.log("Starting bridge monitor");
+ const foreignWormholeChainIds = ["wormhole.CHAIN_ID_SEPOLIA", "wormhole.CHAIN_ID_OPTIMISM_SEPOLIA"];
+
// Write config file
const config = `
const wormhole = require("@certusone/wormhole-sdk");
@@ -149,12 +184,20 @@ async function setupBridging(homeRpcUrl, foreignRpcUrl) {
[wormhole.CHAIN_ID_ARBITRUM_SEPOLIA]: {
endpoints: ["${homeRpcUrl}"],
colonyBridgeAddress: "${homeColonyBridge.address}",
- },
- [wormhole.CHAIN_ID_SEPOLIA]: {
+ payForGas: true,
+ evmChainId: ${homeChainId}
+ },${foreignRpcUrls
+ .map(
+ (foreignRpcUrl, index) => `
+ [${foreignWormholeChainIds[index]}]: {
endpoints: ["${foreignRpcUrl}"],
- colonyBridgeAddress: "${foreignColonyBridge.address}",
- },
- },
+ colonyBridgeAddress: "${remoteColonyBridgeAddresses[index]}",
+ payForGas: ${index % 2 === 0},
+ evmChainId: ${foreignChainIds[index]}
+ },`,
+ )
+ .join("")}
+ },
};
`;
fs.writeFileSync(path.resolve(__dirname, "..", "packages", "wormhole-relayer", "config.js"), config);
@@ -164,8 +207,19 @@ async function setupBridging(homeRpcUrl, foreignRpcUrl) {
stdio: "inherit",
});
+ const wormholeScanMockProcess = spawn("pnpm", ["exec", "tsx", "./src/index.ts"], {
+ cwd: path.resolve(__dirname, "..", "helpers", "wormholescanMock"),
+ stdio: "inherit",
+ env: {
+ ...process.env,
+ PORT: "3001",
+ PROVIDER_URLS: `${homeRpcUrl},${foreignRpcUrls.join(",")}`,
+ },
+ });
+
process.on("exit", () => {
relayerProcess.kill();
+ wormholeScanMockProcess.kill();
});
// Wait until the bridge monitor has connected to the spy
@@ -192,14 +246,90 @@ async function setupBridging(homeRpcUrl, foreignRpcUrl) {
}
console.log(`Home bridge address: ${homeBridge.address}`);
- console.log(`Foreign bridge address: ${foreignBridge.address}`);
- console.log(`Home colony bridge address: ${homeColonyBridge.address}`);
- console.log(`Foreign colony bridge address: ${foreignColonyBridge.address}`);
- console.log(`Gnosis Safe address: ${gnosisSafe.address}`);
- console.log(`Zodiac Bridge module address: ${zodiacBridge.address}`);
- console.log(`ERC721 address: ${erc721.address}`);
- console.log(`Token address: ${token.address}`);
- return { gnosisSafe, resetRelayer, guardianSpy, zodiacBridge, homeBridge, foreignBridge, homeColonyBridge, foreignColonyBridge };
+ console.log(`Foreign bridge addresses: ${foreignBridgeAddresses.join(", ")}`);
+ console.log(`Home colony bridge addresses: ${homeColonyBridge.address}`);
+ console.log(`Foreign colony bridge addresses: ${remoteColonyBridgeAddresses.join(", ")}`);
+ // console.log(`Gnosis Safe addresses: ${gnosisSafe.address}`);
+ // console.log(`Zodiac Bridge module addresses: ${zodiacBridge.address}`);
+ // console.log(`ERC721 addresses: ${erc721.address}`);
+ // console.log(`Token addresses: ${token.address}`);
+
+ for (let i = 0; i < ethersForeignSigners.length; i += 1) {
+ await setForeignBridgeData(homeColonyBridge.address, remoteColonyBridgeAddresses[i], ethersHomeSigner, ethersForeignSigners[i]);
+ await setHomeBridgeData(homeColonyBridge.address, remoteColonyBridgeAddresses[i], ethersHomeSigner, ethersForeignSigners[i]);
+ }
+
+ // TODO: Return all, and handle appropriately where this is called.
+ return {
+ gnosisSafe: gnosisSafes[0],
+ resetRelayer,
+ guardianSpy,
+ zodiacBridge: zodiacBridges[0],
+ homeBridge,
+ foreignBridge: foreignBridges[0],
+ homeColonyBridge,
+ remoteColonyBridge: remoteColonyBridges[0],
+ };
+}
+
+async function setForeignBridgeData(homeColonyBridgeAddress, remoteColonyBridgeAddress, ethersHomeSigner, ethersForeignSigner) {
+ const contractDir = path.resolve(__dirname, "..", "artifacts", "contracts", "bridging");
+ const WormholeBridgeForColony = await loader.load({ contractDir, contractName: "WormholeBridgeForColony" });
+ const ProxyColonyNetwork = await loader.load({ contractDir, contractName: "ProxyColonyNetwork" });
+
+ const bridge = new ethers.Contract(remoteColonyBridgeAddress, WormholeBridgeForColony.abi, ethersForeignSigner);
+
+ const homeChainId = (await ethersHomeSigner.provider.getNetwork()).chainId;
+ const foreignChainId = (await ethersForeignSigner.provider.getNetwork()).chainId;
+
+ let tx = await bridge.setColonyBridgeAddress(foreignChainId, remoteColonyBridgeAddress);
+ await tx.wait();
+ tx = await bridge.setColonyBridgeAddress(homeChainId, homeColonyBridgeAddress);
+ await tx.wait();
+
+ tx = await bridge.setColonyNetworkAddress(NETWORK_ADDRESS);
+ await tx.wait();
+
+ // TODO: Figure out a better way of setting / controlling this?
+ console.log("setting foreign colony bridge address", remoteColonyBridgeAddress);
+
+ const remoteColonyNetwork = new ethers.Contract(NETWORK_ADDRESS, ProxyColonyNetwork.abi, ethersForeignSigner);
+ tx = await remoteColonyNetwork.setColonyBridgeAddress(remoteColonyBridgeAddress);
+ await tx.wait();
+
+ tx = await remoteColonyNetwork.setHomeChainId(homeChainId);
+ await tx.wait();
+}
+
+async function setHomeBridgeData(homeColonyBridgeAddress, remoteColonyBridgeAddress, ethersHomeSigner, ethersForeignSigner) {
+ let contractDir = path.resolve(__dirname, "..", "artifacts", "contracts", "bridging");
+ const WormholeBridgeForColony = await loader.load({ contractDir, contractName: "WormholeBridgeForColony" });
+
+ contractDir = path.resolve(__dirname, "..", "artifacts", "contracts", "colonyNetwork");
+ const IColonyNetwork = await loader.load({ contractDir, contractName: "IColonyNetwork" });
+
+ const bridge = new ethers.Contract(homeColonyBridgeAddress, WormholeBridgeForColony.abi, ethersHomeSigner);
+ const homeChainId = (await ethersHomeSigner.provider.getNetwork()).chainId;
+ const foreignChainId = (await ethersForeignSigner.provider.getNetwork()).chainId;
+
+ let tx = await bridge.setColonyBridgeAddress(foreignChainId, remoteColonyBridgeAddress);
+ await tx.wait();
+ tx = await bridge.setColonyBridgeAddress(homeChainId, homeColonyBridgeAddress);
+ await tx.wait();
+
+ tx = await bridge.setColonyNetworkAddress(NETWORK_ADDRESS);
+ await tx.wait();
+
+ const homeColonyNetwork = new ethers.Contract(NETWORK_ADDRESS, IColonyNetwork.abi, ethersHomeSigner);
+ const mcAddress = await homeColonyNetwork.getMetaColony();
+
+ contractDir = path.resolve(__dirname, "..", "artifacts", "contracts", "colony");
+ const IMetaColony = await loader.load({ contractDir, contractName: "IMetaColony" });
+
+ const homeMetacolony = new ethers.Contract(mcAddress, IMetaColony.abi, ethersHomeSigner);
+
+ tx = await homeMetacolony.setColonyBridgeAddress(homeColonyBridgeAddress);
+ await tx.wait();
}
async function getSig(provider, account, dataHash) {
@@ -231,14 +361,16 @@ async function deployBridge(signer) {
let tx = await bridge.setWormholeAddress(wormhole.address);
await tx.wait();
- tx = await bridge.setChainIdMapping([265669100, 265669101], [10003, 10002]);
+
+ // TODO: These aren't all needed on every bridge
+ tx = await bridge.setChainIdMapping([265669100, 265669101, 265669102], [10003, 10002, 10005]);
await tx.wait();
return [wormhole, bridge];
}
if (process.argv.includes("start-bridging-environment")) {
- setupBridging("http://127.0.0.1:8545", "http://127.0.0.1:8546");
+ setupBridging("http://127.0.0.1:8545", "http://127.0.0.1:8546", true);
}
-module.exports = { setupBridging, deployBridge };
+module.exports = { setupBridging, deployBridge, setHomeBridgeData, setForeignBridgeData };
diff --git a/test/contracts-network/colony-arbitrary-transactions.js b/test/contracts-network/colony-arbitrary-transactions.js
index 26cd844c4f..9ea62b42fd 100644
--- a/test/contracts-network/colony-arbitrary-transactions.js
+++ b/test/contracts-network/colony-arbitrary-transactions.js
@@ -49,6 +49,19 @@ contract("Colony Arbitrary Transactions", (accounts) => {
expect(balancePost.sub(balancePre)).to.eq.BN(WAD);
});
+ it("makeSingleArbitraryTransaction can only be called by the colony on itself", async () => {
+ const action = await encodeTxData(token, "mint", [WAD]);
+ await checkErrorRevert(colony.makeSingleArbitraryTransaction(token.address, action, { from: USER0 }), "colony-not-self");
+ });
+
+ it("makeArbitraryTransactions must be called with the same number of addresses and actions", async () => {
+ const action = await encodeTxData(token, "mint", [WAD]);
+ await checkErrorRevert(
+ colony.makeArbitraryTransactions([token.address, token.address], [action], true),
+ "colony-targets-and-actions-length-mismatch",
+ );
+ });
+
it("should be able to make multiple arbitrary transactions", async () => {
const action = await encodeTxData(token, "mint", [WAD]);
const action2 = await encodeTxData(token, "mint", [WAD.muln(2)]);
diff --git a/test/contracts-network/colony-expenditure.js b/test/contracts-network/colony-expenditure.js
index f34d185ae5..f76c125c65 100644
--- a/test/contracts-network/colony-expenditure.js
+++ b/test/contracts-network/colony-expenditure.js
@@ -14,6 +14,7 @@ const {
getBlockTime,
bn2bytes32,
upgradeColonyOnceThenToLatest,
+ getChainId,
} = require("../../helpers/test-helper");
const { fundColonyWithTokens, setupRandomColony } = require("../../helpers/test-data-generator");
const { setupEtherRouter } = require("../../helpers/upgradable-contracts");
@@ -234,6 +235,10 @@ contract("Colony Expenditure", (accounts) => {
it("should allow arbitrators to update the metadata", async () => {
const setExpenditureMetadata = colony.methods["setExpenditureMetadata(uint256,uint256,uint256,string)"];
+
+ // Try with a bad proof
+ await checkErrorRevert(setExpenditureMetadata(1, 0, expenditureId, IPFS_HASH, { from: ARBITRATOR }), "ds-auth-invalid-domain-inheritance");
+
const tx = await setExpenditureMetadata(1, UINT256_MAX, expenditureId, IPFS_HASH, { from: ARBITRATOR });
await expectEvent(tx, "ExpenditureMetadataSet", [ARBITRATOR, expenditureId, IPFS_HASH]);
@@ -642,6 +647,15 @@ contract("Colony Expenditure", (accounts) => {
await checkErrorRevert(colony.finalizeExpenditure(expenditureId, { from: ADMIN }), "colony-expenditure-not-draft-or-locked");
});
+ it("should not allow expenditures to be finalized if they are not fully funded", async () => {
+ await colony.setExpenditurePayout(expenditureId, SLOT0, token.address, WAD, { from: ADMIN });
+ await checkErrorRevert(colony.finalizeExpenditure(expenditureId, { from: ADMIN }), "colony-expenditure-not-funded");
+ await checkErrorRevert(
+ colony.finalizeExpenditureViaArbitration(1, UINT256_MAX, expenditureId, { from: ARBITRATOR }),
+ "colony-expenditure-not-funded",
+ );
+ });
+
it("should allow owners to finalize expenditures from locked state", async () => {
await colony.lockExpenditure(expenditureId, { from: ADMIN });
@@ -754,7 +768,10 @@ contract("Colony Expenditure", (accounts) => {
);
await colony.finalizeExpenditure(expenditureId, { from: ADMIN });
const tx = await colony.claimExpenditurePayout(expenditureId, SLOT0, token.address);
- await expectEvent(tx, "PayoutClaimed", [accounts[0], expenditureId, SLOT0, token.address, WAD.divn(100).muln(99).subn(1)]);
+
+ const chainId = await getChainId();
+
+ await expectEvent(tx, "PayoutClaimed", [accounts[0], expenditureId, SLOT0, chainId, token.address, WAD.divn(100).muln(99).subn(1)]);
await expectEvent(tx, "PayoutClaimed", [accounts[0], expenditure.fundingPotId, token.address, WAD.divn(100).muln(99).subn(1)]);
});
diff --git a/test/contracts-network/colony-funding.js b/test/contracts-network/colony-funding.js
index 9dbc25f833..069ea62323 100755
--- a/test/contracts-network/colony-funding.js
+++ b/test/contracts-network/colony-funding.js
@@ -16,6 +16,7 @@ const {
SLOT2,
ROOT_ROLE,
ADDRESS_ZERO,
+ LIFI_ADDRESS,
} = require("../../helpers/constants");
const {
@@ -25,7 +26,16 @@ const {
setupFundedExpenditure,
setupRandomToken,
} = require("../../helpers/test-data-generator");
-const { getTokenArgs, checkErrorRevert, web3GetBalance, removeSubdomainLimit, expectEvent, rolesToBytes32 } = require("../../helpers/test-helper");
+const {
+ getTokenArgs,
+ checkErrorRevert,
+ web3GetBalance,
+ removeSubdomainLimit,
+ expectEvent,
+ rolesToBytes32,
+ getChainId,
+ encodeTxData,
+} = require("../../helpers/test-helper");
const { setupDomainTokenReceiverResolver } = require("../../helpers/upgradable-contracts");
const { expect } = chai;
@@ -38,6 +48,8 @@ const Token = artifacts.require("Token");
const Resolver = artifacts.require("Resolver");
const DomainTokenReceiver = artifacts.require("DomainTokenReceiver");
const TokenAuthority = artifacts.require("contracts/common/TokenAuthority.sol:TokenAuthority");
+const ToggleableToken = artifacts.require("ToggleableToken");
+const LiFiFacetProxyMock = artifacts.require("LiFiFacetProxyMock");
contract("Colony Funding", (accounts) => {
const MANAGER = accounts[0];
@@ -48,6 +60,7 @@ contract("Colony Funding", (accounts) => {
let otherToken;
let colonyNetwork;
let metaColony;
+ let chainId;
before(async () => {
const cnAddress = (await EtherRouter.deployed()).address;
@@ -56,6 +69,8 @@ contract("Colony Funding", (accounts) => {
const metaColonyAddress = await colonyNetwork.getMetaColony();
metaColony = await IMetaColony.at(metaColonyAddress);
+
+ chainId = await getChainId();
});
beforeEach(async () => {
@@ -862,5 +877,200 @@ contract("Colony Funding", (accounts) => {
expect(resolverAfter).to.not.equal(resolver);
expect(resolverAfter).to.equal(newResolver.address);
});
+
+ it("should not be able to claim funds for a domain that does not exist", async () => {
+ await checkErrorRevert(colony.claimDomainFunds(ethers.constants.AddressZero, 2), "colony-funding-domain-does-not-exist");
+ });
+
+ it("only a colony can call idempotentDeployDomainTokenReceiver on Network", async () => {
+ await checkErrorRevert(colonyNetwork.idempotentDeployDomainTokenReceiver(2), "colony-caller-must-be-colony");
+ });
+
+ it("If transfer fails from receiver, then the funds are not claimed", async () => {
+ await colony.addDomain(1, UINT256_MAX, 1);
+ const receiverAddress = await colonyNetwork.getDomainTokenReceiverAddress(colony.address, 2);
+
+ const toggleableToken = await ToggleableToken.new(200);
+ await toggleableToken.mint(receiverAddress, 100);
+
+ await toggleableToken.toggleLock();
+
+ // Try to claim the funds
+ await checkErrorRevert(colony.claimDomainFunds(toggleableToken.address, 2), "colony-funding-transfer-failed");
+ });
+
+ it("If the receiver resolver is updated, then the resolver is updated at the next claim", async () => {
+ await colony.addDomain(1, UINT256_MAX, 1);
+ const receiverAddress = await colonyNetwork.getDomainTokenReceiverAddress(colony.address, 2);
+ // Send 100 wei
+ await otherToken.mint(receiverAddress, 100);
+ await colony.claimDomainFunds(otherToken.address, 2);
+
+ const receiverAsEtherRouter = await EtherRouter.at(receiverAddress);
+ const resolver = await receiverAsEtherRouter.resolver();
+
+ // Update the resolver
+ const newResolver = await Resolver.new();
+ const domainTokenReceiver = await DomainTokenReceiver.new();
+
+ await setupDomainTokenReceiverResolver(colonyNetwork, domainTokenReceiver, newResolver);
+
+ await otherToken.mint(receiverAddress, 50);
+ await colony.claimDomainFunds(otherToken.address, 2);
+
+ const resolverAfter = await receiverAsEtherRouter.resolver();
+ expect(resolverAfter).to.not.equal(resolver);
+ expect(resolverAfter).to.equal(newResolver.address);
+ });
+ });
+
+ describe("when exchanging tokens via LiFi", () => {
+ let domain1;
+ let domain2;
+ let domain2ReceiverAddress;
+ let lifi;
+ let lifiEthers;
+ beforeEach(async () => {
+ await token.mint(colony.address, 200);
+ await colony.claimColonyFunds(token.address);
+ await colony.addDomain(1, UINT256_MAX, 1);
+
+ domain1 = await colony.getDomain(1);
+ domain2 = await colony.getDomain(2);
+
+ // Move 50 tokens from the colony to domain 2
+ await colony.moveFundsBetweenPots(1, UINT256_MAX, 1, UINT256_MAX, 0, domain1.fundingPotId, domain2.fundingPotId, 50, chainId, token.address);
+
+ domain2ReceiverAddress = await colonyNetwork.getDomainTokenReceiverAddress(colony.address, 2);
+
+ lifi = await LiFiFacetProxyMock.at(LIFI_ADDRESS);
+ const ethersProvider = new ethers.providers.Web3Provider(web3.currentProvider);
+ lifiEthers = new ethers.Contract(LIFI_ADDRESS, LiFiFacetProxyMock.abi, ethersProvider);
+ });
+
+ it("can exchange tokens in a domain via LiFi", async () => {
+ const txdata = lifi.contract.methods["swapTokensMock(uint256,address,uint256,address,address,uint256)"](
+ chainId,
+ token.address,
+ chainId,
+ otherToken.address,
+ domain2ReceiverAddress,
+ 50,
+ ).encodeABI();
+
+ const tx = await colony.exchangeTokensViaLiFi(1, 0, 2, txdata, 0, chainId, token.address, 50);
+ const swapEvent = tx.receipt.rawLogs
+ .filter((e) => e.address === LIFI_ADDRESS)
+ .map((e) => lifiEthers.interface.parseLog(e))
+ .filter((e) => e.name === "SwapTokens")[0];
+ expect(swapEvent).to.not.be.undefined;
+
+ // Okay, so we saw the SwapTokens event. Let's do vaguely what it said for the test,
+ // but in practise this would be the responsibility of whatever entity we've paid to do it
+ // through LiFi.
+ await otherToken.mint(swapEvent.args._toAddress, swapEvent.args._amount); // Implicit 1:1 exchange rate
+
+ // Now claim the tokens
+ await colony.claimDomainFunds(otherToken.address, 2);
+
+ // See if bookkeeping was tracked correctly
+ const domain = await colony.getDomain(2);
+ const balance = await colony.getFundingPotBalance(domain.fundingPotId, otherToken.address);
+ expect(balance).to.eq.BN(50);
+ });
+
+ it("should not mess up approval bookkeeping when exchanging tokens via LiFi", async () => {
+ const action1 = await encodeTxData(token, "approve", [LIFI_ADDRESS, 80]);
+ await colony.makeArbitraryTransaction(token.address, action1);
+
+ const txdata = lifi.contract.methods["swapTokensMock(uint256,address,uint256,address,address,uint256)"](
+ chainId,
+ token.address,
+ chainId,
+ otherToken.address,
+ domain2ReceiverAddress,
+ 40,
+ ).encodeABI();
+
+ await colony.exchangeTokensViaLiFi(1, 0, 2, txdata, 0, chainId, token.address, 50);
+ await otherToken.mint(domain2ReceiverAddress, 50); // Better than 1:1 exchange rate
+
+ const approval = await colony.getTokenApproval(token.address, LIFI_ADDRESS);
+ expect(approval).to.be.eq.BN(80);
+ const allApprovals = await colony.getTotalTokenApproval(token.address);
+ expect(allApprovals).to.be.eq.BN(80);
+ const tokenApproval = await token.allowance(colony.address, LIFI_ADDRESS);
+ expect(tokenApproval).to.be.eq.BN(80);
+ });
+
+ it("'lying' calls of exchangeTokensViaLiFi trying to spend other tokens are caught", async () => {
+ await fundColonyWithTokens(colony, otherToken, 100);
+ await colony.claimColonyFunds(otherToken.address);
+
+ const action1 = await encodeTxData(otherToken, "approve", [LIFI_ADDRESS, 80]);
+ await colony.makeArbitraryTransaction(otherToken.address, action1);
+
+ const txdata = lifi.contract.methods["swapTokensMock(uint256,address,uint256,address,address,uint256)"](
+ chainId,
+ otherToken.address,
+ chainId,
+ otherToken.address,
+ domain2ReceiverAddress,
+ 40,
+ ).encodeABI();
+ await checkErrorRevert(colony.exchangeTokensViaLiFi(1, 0, 2, txdata, 0, chainId, token.address, 50), "colony-unexpected-exchange");
+ });
+
+ it("'lying' calls of exchangeTokensViaLiFi trying to spend already-approved tokens are caught", async () => {
+ const action1 = await encodeTxData(token, "approve", [LIFI_ADDRESS, 80]);
+ await colony.makeArbitraryTransaction(token.address, action1);
+
+ const txdata = lifi.contract.methods["swapTokensMock(uint256,address,uint256,address,address,uint256)"](
+ chainId,
+ token.address,
+ chainId,
+ otherToken.address,
+ domain2ReceiverAddress,
+ 60,
+ ).encodeABI();
+ await checkErrorRevert(
+ colony.exchangeTokensViaLiFi(1, 0, 2, txdata, 0, chainId, token.address, 50),
+ "colony-more-than-intended-allowance-used",
+ );
+ });
+
+ it("If LiFi transaction was cheaper than expected, shouldn't leave extra allowance behind", async () => {
+ const txdata = lifi.contract.methods["swapTokensMock(uint256,address,uint256,address,address,uint256)"](
+ chainId,
+ token.address,
+ chainId,
+ otherToken.address,
+ domain2ReceiverAddress,
+ 40,
+ ).encodeABI();
+
+ await colony.exchangeTokensViaLiFi(1, 0, 2, txdata, 0, chainId, token.address, 50);
+
+ const approval = await token.allowance(colony.address, LIFI_ADDRESS);
+ expect(approval).to.be.eq.BN(0);
+ });
+
+ it("shouldn't use tokens that are already approved if swapping in root", async () => {
+ const action1 = await encodeTxData(token, "approve", [ADDRESS_ZERO, 140]);
+ await colony.makeArbitraryTransaction(token.address, action1);
+
+ // 10 remain unapproved in the root domain
+ // Try to spend 50 with LiFi
+
+ const txdata = lifi.contract.methods["swapTokensMock(uint256,address,uint256,address,address,uint256)"](
+ chainId,
+ token.address,
+ chainId,
+ otherToken.address,
+ domain2ReceiverAddress,
+ 50,
+ ).encodeABI();
+ await checkErrorRevert(colony.exchangeTokensViaLiFi(1, UINT256_MAX, 1, txdata, 0, chainId, token.address, 50), "colony-insufficient-funds");
+ });
});
});
diff --git a/test/contracts-network/colony-network-extensions.js b/test/contracts-network/colony-network-extensions.js
index 2f0de76756..73eba4ff02 100644
--- a/test/contracts-network/colony-network-extensions.js
+++ b/test/contracts-network/colony-network-extensions.js
@@ -305,6 +305,13 @@ contract("Colony Network Extensions", (accounts) => {
});
describe("using extensions", () => {
+ it("extension-managing functions on Network cannot be called by non-colony addresses", async () => {
+ await checkErrorRevert(colonyNetwork.installExtension(TEST_EXTENSION, 1, { from: ROOT }), "colony-caller-must-be-colony");
+ await checkErrorRevert(colonyNetwork.upgradeExtension(TEST_EXTENSION, 2, { from: ROOT }), "colony-caller-must-be-colony");
+ await checkErrorRevert(colonyNetwork.deprecateExtension(TEST_EXTENSION, true, { from: ROOT }), "colony-caller-must-be-colony");
+ await checkErrorRevert(colonyNetwork.uninstallExtension(TEST_EXTENSION, { from: ROOT }), "colony-caller-must-be-colony");
+ });
+
it("allows network-managed extensions to lock and unlock tokens", async () => {
const tokenLockingAddress = await colonyNetwork.getTokenLocking();
const tokenLocking = await ITokenLocking.at(tokenLockingAddress);
diff --git a/test/contracts-network/colony-network-recovery.js b/test/contracts-network/colony-network-recovery.js
index 4f4f139972..219359ab9e 100644
--- a/test/contracts-network/colony-network-recovery.js
+++ b/test/contracts-network/colony-network-recovery.js
@@ -193,14 +193,13 @@ contract("Colony Network Recovery", (accounts) => {
await checkErrorRevert(colonyNetwork.setPayoutWhitelist(ADDRESS_ZERO, true), "colony-in-recovery-mode");
await checkErrorRevert(colonyNetwork.claimMiningReward(ADDRESS_ZERO), "colony-in-recovery-mode");
await checkErrorRevert(colonyNetwork.startTokenAuction(ADDRESS_ZERO), "colony-in-recovery-mode");
- await checkErrorRevert(colonyNetwork.bridgeSkillIfNotMiningChain(1), "colony-in-recovery-mode");
- await checkErrorRevert(colonyNetwork.bridgePendingReputationUpdate(ADDRESS_ZERO, 0), "colony-in-recovery-mode");
- await checkErrorRevert(colonyNetwork.bridgeCurrentRootHash(ADDRESS_ZERO), "colony-in-recovery-mode");
- await checkErrorRevert(colonyNetwork.addReputationUpdateLogFromBridge(ADDRESS_ZERO, ADDRESS_ZERO, 0, 0, 0), "colony-in-recovery-mode");
- await checkErrorRevert(colonyNetwork.addPendingReputationUpdate(0, ADDRESS_ZERO), "colony-in-recovery-mode");
- await checkErrorRevert(colonyNetwork.setReputationRootHashFromBridge(HASHZERO, 0, 0), "colony-in-recovery-mode");
await checkErrorRevert(colonyNetwork.setDomainTokenReceiverResolver(ADDRESS_ZERO), "colony-in-recovery-mode");
- await checkErrorRevert(colonyNetwork.idempotentDeployDomainTokenReceiver(ADDRESS_ZERO), "colony-in-recovery-mode");
+ await checkErrorRevert(colonyNetwork.idempotentDeployDomainTokenReceiver(ADDRESS_ZERO), "colony-domain-receiver-management-stopped");
+ await checkErrorRevert(colonyNetwork.bridgeMessage(1, "0x00000000"), "colony-in-recovery-mode");
+ await checkErrorRevert(colonyNetwork.bridgeMessageToNetwork(1, "0x00000000"), "colony-in-recovery-mode");
+ await checkErrorRevert(colonyNetwork.createProxyColony(1, HASHZERO), "colony-in-recovery-mode");
+ await checkErrorRevert(colonyNetwork.idempotentDeployDomainTokenReceiver(1), "colony-domain-receiver-management-stopped");
+
await colonyNetwork.approveExitRecovery();
await colonyNetwork.exitRecoveryMode();
});
diff --git a/test/contracts-network/colony-network.js b/test/contracts-network/colony-network.js
index f84384cc4d..f2f1f44dcf 100755
--- a/test/contracts-network/colony-network.js
+++ b/test/contracts-network/colony-network.js
@@ -26,7 +26,7 @@ const {
setStorageSlot,
} = require("../../helpers/test-helper");
-const { CURR_VERSION, MIN_STAKE, IPFS_HASH, ADDRESS_ZERO, WAD } = require("../../helpers/constants");
+const { CURR_VERSION, IPFS_HASH, ADDRESS_ZERO, WAD } = require("../../helpers/constants");
const { setupENSRegistrar } = require("../../helpers/upgradable-contracts");
const { expect } = chai;
@@ -203,16 +203,6 @@ contract("Colony Network", (accounts) => {
await checkErrorRevert(colonyNetwork.startNextCycle(), "colony-reputation-mining-clny-token-invalid-address");
});
-
- it('should not allow "punishStakers" to be called from an account that is not the mining cycle', async () => {
- const chainId = await getChainId();
- await metaColony.initialiseReputationMining(chainId, ethers.constants.HashZero, 0);
-
- await checkErrorRevert(
- colonyNetwork.punishStakers([accounts[0], accounts[1]], MIN_STAKE),
- "colony-reputation-mining-sender-not-active-reputation-cycle",
- );
- });
});
describe("when creating new colonies at a specific version", () => {
diff --git a/test/contracts-network/colony-recovery.js b/test/contracts-network/colony-recovery.js
index b785f7d102..8fc4b7beae 100644
--- a/test/contracts-network/colony-recovery.js
+++ b/test/contracts-network/colony-recovery.js
@@ -197,6 +197,7 @@ contract("Colony Recovery", (accounts) => {
await checkErrorRevert(metaColony.claimExpenditurePayout(0, 0, ADDRESS_ZERO), "colony-in-recovery-mode");
await checkErrorRevert(metaColony.moveFundsBetweenPots(0, 0, 0, 0, 0, 0, 0, 0, ADDRESS_ZERO), "colony-in-recovery-mode");
await checkErrorRevert(metaColony.moveFundsBetweenPots(0, 0, 0, 0, 0, 0, ADDRESS_ZERO), "colony-in-recovery-mode");
+ await checkErrorRevert(metaColony.moveFundsBetweenPots(0, 0, 0, 0, 0, 0, 0, 0, 0, ADDRESS_ZERO), "colony-in-recovery-mode");
await checkErrorRevert(metaColony.claimColonyFunds(ADDRESS_ZERO), "colony-in-recovery-mode");
await checkErrorRevert(metaColony.startNextRewardPayout(ADDRESS_ZERO, HASHZERO, HASHZERO, 0, []), "colony-in-recovery-mode");
await checkErrorRevert(metaColony.claimRewardPayout(0, [0, 0, 0, 0, 0, 0, 0], HASHZERO, HASHZERO, 0, []), "colony-in-recovery-mode");
@@ -204,6 +205,7 @@ contract("Colony Recovery", (accounts) => {
await checkErrorRevert(metaColony.setExpenditurePayouts(0, [], ADDRESS_ZERO, []), "colony-in-recovery-mode");
await checkErrorRevert(metaColony.setExpenditurePayout(0, 0, ADDRESS_ZERO, 0), "colony-in-recovery-mode");
await checkErrorRevert(metaColony.setExpenditurePayout(1, UINT256_MAX, 0, 0, ADDRESS_ZERO, 0), "colony-in-recovery-mode");
+ await checkErrorRevert(metaColony.setExpenditureSkill(1, 1, 1), "colony-in-recovery-mode");
await checkErrorRevert(metaColony.enterRecoveryMode(), "colony-in-recovery-mode");
await checkErrorRevert(metaColony.burnTokens(ADDRESS_ZERO, 0), "colony-in-recovery-mode");
await checkErrorRevert(metaColony.registerColonyLabel("", ""), "colony-in-recovery-mode");
@@ -211,6 +213,8 @@ contract("Colony Recovery", (accounts) => {
await checkErrorRevert(metaColony.makeArbitraryTransaction(ADDRESS_ZERO, HASHZERO), "colony-in-recovery-mode");
await checkErrorRevert(metaColony.makeArbitraryTransactions([], [], true), "colony-in-recovery-mode");
await checkErrorRevert(metaColony.makeSingleArbitraryTransaction(ADDRESS_ZERO, HASHZERO), "colony-in-recovery-mode");
+ await checkErrorRevert(metaColony.makeProxyArbitraryTransaction(1, ADDRESS_ZERO, HASHZERO), "colony-in-recovery-mode");
+ await checkErrorRevert(metaColony.multicallProxyNetwork(1, []), "colony-in-recovery-mode");
await checkErrorRevert(metaColony.updateApprovalAmount(ADDRESS_ZERO, ADDRESS_ZERO), "colony-in-recovery-mode");
await checkErrorRevert(metaColony.finalizeRewardPayout(1), "colony-in-recovery-mode");
await checkErrorRevert(metaColony.claimDomainFunds(ADDRESS_ZERO, 1), "colony-in-recovery-mode");
diff --git a/test/contracts-network/colony.js b/test/contracts-network/colony.js
index ebc1939eb5..9342d42cb8 100755
--- a/test/contracts-network/colony.js
+++ b/test/contracts-network/colony.js
@@ -13,6 +13,7 @@ const {
expectAllEvents,
expectEvent,
upgradeColonyOnceThenToLatest,
+ bn2bytes32,
} = require("../../helpers/test-helper");
const {
setupRandomColony,
@@ -237,6 +238,14 @@ contract("Colony", (accounts) => {
await expectEvent(tx, "FundingPotAdded", [fundingPotCount]);
await expectEvent(tx, "DomainMetadata", [accounts[0], domainCount, IPFS_HASH]);
});
+
+ it("should require a valid permission proof", async () => {
+ await colony.addDomain(1, UINT256_MAX, 1);
+
+ // Remove permission
+ await colony.setUserRoles(1, UINT256_MAX, USER0, 1, bn2bytes32(0));
+ await checkErrorRevert(colony.addDomain(1, UINT256_MAX, 1), "ds-auth-unauthorized");
+ });
});
describe("when editing domains", () => {
@@ -250,6 +259,15 @@ contract("Colony", (accounts) => {
await colony.addDomain(1, UINT256_MAX, 1);
await expectNoEvent(colony.editDomain(1, 0, 2, ""), "DomainMetadata");
});
+
+ it("should require a valid permission proof", async () => {
+ await colony.addDomain(1, UINT256_MAX, 1);
+ await colony.editDomain(1, 0, 2, IPFS_HASH);
+
+ // Remove permission
+ await colony.setUserRoles(1, UINT256_MAX, USER0, 1, bn2bytes32(0));
+ await checkErrorRevert(colony.editDomain(1, 0, 2, IPFS_HASH), "ds-auth-unauthorized");
+ });
});
describe("when deprecating domains", () => {
diff --git a/test/contracts-network/metatx-token.js b/test/contracts-network/metatx-token.js
index 88139cbf0b..320efaacb4 100644
--- a/test/contracts-network/metatx-token.js
+++ b/test/contracts-network/metatx-token.js
@@ -289,6 +289,12 @@ contract("MetaTxToken", (accounts) => {
const locked = await metaTxToken.locked();
expect(locked).to.be.true;
});
+
+ it("only owner can call setOwner", async () => {
+ await checkErrorRevert(metaTxToken.setOwner(USER1, { from: USER1 }), "ds-auth-unauthorized");
+ await metaTxToken.setOwner(USER1, { from: USER0 });
+ await metaTxToken.setOwner(USER0, { from: USER1 });
+ });
});
describe("when working with ether transfers", () => {
diff --git a/test/contracts-network/reputation-basic-functionality.js b/test/contracts-network/reputation-basic-functionality.js
index bed0d2bd07..39b8d77edc 100644
--- a/test/contracts-network/reputation-basic-functionality.js
+++ b/test/contracts-network/reputation-basic-functionality.js
@@ -6,7 +6,7 @@ const bnChai = require("bn-chai");
const { ethers } = require("ethers");
const { giveUserCLNYTokens, giveUserCLNYTokensAndStake } = require("../../helpers/test-data-generator");
-const { MIN_STAKE, MINING_CYCLE_DURATION, DECAY_RATE, CHALLENGE_RESPONSE_WINDOW_DURATION } = require("../../helpers/constants");
+const { MIN_STAKE, MINING_CYCLE_DURATION, DECAY_RATE, CHALLENGE_RESPONSE_WINDOW_DURATION, ADDRESS_ZERO } = require("../../helpers/constants");
const { forwardTime, checkErrorRevert, getActiveRepCycle, advanceMiningCycleNoContest, getBlockTime } = require("../../helpers/test-helper");
const { expect } = chai;
@@ -213,9 +213,23 @@ contract("Reputation mining - basic functionality", (accounts) => {
await checkErrorRevert(repCycle.resetWindow(), "colony-reputation-mining-sender-not-network");
});
- it('should not allow "setReputationRootHash" to be called from an account that is not a ReputationMiningCycle', async () => {
+ it("should not allow reputation-mining functions to be called from an account that is not an active ReputationMiningCycle", async () => {
+ const inactiveRepCycleAddr = await colonyNetwork.getReputationMiningCycle(false);
+
+ await checkErrorRevert(
+ colonyNetwork.setReputationRootHash("0x000001", 10, [accounts[0], accounts[1]], { from: inactiveRepCycleAddr }),
+ "colony-reputation-mining-sender-not-active-reputation-cycle",
+ );
+ await checkErrorRevert(
+ colonyNetwork.punishStakers([accounts[0], accounts[1]], MIN_STAKE, { from: inactiveRepCycleAddr }),
+ "colony-reputation-mining-sender-not-active-reputation-cycle",
+ );
+ await checkErrorRevert(
+ colonyNetwork.reward(accounts[0], MIN_STAKE, { from: inactiveRepCycleAddr }),
+ "colony-reputation-mining-sender-not-active-reputation-cycle",
+ );
await checkErrorRevert(
- colonyNetwork.setReputationRootHash("0x000001", 10, [accounts[0], accounts[1]]),
+ colonyNetwork.burnUnneededRewards(0, { from: inactiveRepCycleAddr }),
"colony-reputation-mining-sender-not-active-reputation-cycle",
);
});
@@ -258,6 +272,38 @@ contract("Reputation mining - basic functionality", (accounts) => {
await checkErrorRevert(inactiveRepCycle.initialise(MINER1, MINER2), "colony-reputation-mining-cycle-already-initialised");
});
+
+ it("functions that should only be after initialisation cannot be called before", async () => {
+ const before = await web3.eth.getStorageAt(colonyNetwork.address, 17);
+ const ethersProvider = new ethers.providers.Web3Provider(web3.currentProvider);
+ await ethersProvider.send("hardhat_setStorageAt", [
+ colonyNetwork.address,
+ ethers.utils.hexZeroPad(ethers.utils.hexlify(17), 32),
+ ethers.utils.hexZeroPad(ethers.utils.hexlify(0), 32),
+ ]);
+
+ await checkErrorRevert(colonyNetwork.startNextCycle(), "colony-reputation-mining-not-initialised");
+ await checkErrorRevert(colonyNetwork.setMiningDelegate(ADDRESS_ZERO, false), "colony-reputation-mining-not-initialised");
+ await checkErrorRevert(colonyNetwork.setReputationRootHash("0x00", 0, [ADDRESS_ZERO]), "colony-reputation-mining-not-initialised");
+ await checkErrorRevert(colonyNetwork.punishStakers([ADDRESS_ZERO], 0), "colony-reputation-mining-not-initialised");
+ await checkErrorRevert(colonyNetwork.reward(ADDRESS_ZERO, 0), "colony-reputation-mining-not-initialised");
+ await checkErrorRevert(colonyNetwork.claimMiningReward(ADDRESS_ZERO), "colony-reputation-mining-not-initialised");
+ await checkErrorRevert(colonyNetwork.unstakeForMining(0), "colony-reputation-mining-not-initialised");
+ await checkErrorRevert(colonyNetwork.burnUnneededRewards(0), "colony-reputation-mining-not-initialised");
+ await checkErrorRevert(colonyNetwork.setReputationMiningCycleReward(0), "colony-reputation-mining-not-initialised");
+
+ // Put in to recovery mode
+ await colonyNetwork.enterRecoveryMode();
+
+ await checkErrorRevert(
+ colonyNetwork.setReplacementReputationUpdateLogEntry(ADDRESS_ZERO, 0, ADDRESS_ZERO, 0, 0, ADDRESS_ZERO, 0, 0),
+ "colony-reputation-mining-not-initialised",
+ );
+ await colonyNetwork.approveExitRecovery();
+ await colonyNetwork.exitRecoveryMode();
+
+ await ethersProvider.send("hardhat_setStorageAt", [colonyNetwork.address, ethers.utils.hexZeroPad(ethers.utils.hexlify(17), 32), before]);
+ });
});
describe("when reading reputation mining constant properties", async () => {
diff --git a/test/cross-chain/cross-chain.js b/test/cross-chain/cross-chain.js
index 60ee03649c..f462e1c6e0 100644
--- a/test/cross-chain/cross-chain.js
+++ b/test/cross-chain/cross-chain.js
@@ -23,20 +23,38 @@ const { expect } = chai;
chai.use(bnChai(web3.utils.BN));
const IColonyNetwork = artifacts.require("IColonyNetwork");
-const EtherRouterCreate3 = artifacts.require("EtherRouterCreate3");
const EtherRouter = artifacts.require("EtherRouter");
const IMetaColony = artifacts.require("IMetaColony");
const Token = artifacts.require("Token");
const IColony = artifacts.require("IColony");
-const ICreateX = artifacts.require("ICreateX");
-const IReputationMiningCycle = artifacts.require("IReputationMiningCycle");
-const WormholeBridgeForColony = artifacts.require("WormholeBridgeForColony");
-const { setupBridging, deployBridge } = require("../../scripts/setup-bridging-contracts");
-
-const { MINING_CYCLE_DURATION, CHALLENGE_RESPONSE_WINDOW_DURATION, ROOT_ROLE, CURR_VERSION, CREATEX_ADDRESS } = require("../../helpers/constants");
-const { forwardTime, checkErrorRevertEthers, revert, snapshot, evmChainIdToWormholeChainId } = require("../../helpers/test-helper");
+const ProxyColonyNetwork = artifacts.require("ProxyColonyNetwork");
+const ProxyColony = artifacts.require("ProxyColony");
+const MetaTxToken = artifacts.require("MetaTxToken");
+const OneTxPayment = artifacts.require("OneTxPayment");
+const LiFiFacetProxyMock = artifacts.require("LiFiFacetProxyMock");
+const IWormhole = artifacts.require("IWormhole");
+// const { assert } = require("console");
+
+const { setupBridging, setForeignBridgeData, setHomeBridgeData } = require("../../scripts/setup-bridging-contracts");
+
+const {
+ MINING_CYCLE_DURATION,
+ CHALLENGE_RESPONSE_WINDOW_DURATION,
+ ROOT_ROLE,
+ CURR_VERSION,
+ CREATEX_ADDRESS,
+ NETWORK_ADDRESS,
+ HASHZERO,
+ LIFI_ADDRESS,
+ ARBITRATION_ROLE,
+ FUNDING_ROLE,
+ ADMINISTRATION_ROLE,
+ PANIC,
+} = require("../../helpers/constants");
+const { forwardTime, checkErrorRevertEthers, revert, snapshot, evmChainIdToWormholeChainId, rolesToBytes32 } = require("../../helpers/test-helper");
const ReputationMinerTestWrapper = require("../../packages/reputation-miner/test/ReputationMinerTestWrapper");
const { TruffleLoader } = require("../../packages/package-utils");
+const { getMetaTransactionParameters } = require("../../helpers/test-data-generator");
const UINT256_MAX_ETHERS = ethers.BigNumber.from(2).pow(256).sub(1);
@@ -46,24 +64,24 @@ const contractLoader = new TruffleLoader({
contract("Cross-chain", (accounts) => {
let homeColony;
- let foreignColony;
let homeColonyNetwork;
- let foreignColonyNetwork;
+ let proxyColony;
+ let remoteColonyNetwork;
let homeBridge;
let foreignBridge;
let homeColonyBridge;
- let foreignColonyBridge;
+ let remoteColonyBridge;
let gnosisSafe;
let zodiacBridge;
let guardianSpy;
let homeChainId;
let foreignChainId;
let wormholeHomeChainId;
- let wormholeForeignChainId;
+ // let wormholeForeignChainId;
let resetRelayer;
let homeMetacolony;
- let foreignMetacolony;
+ let proxyMetacolony;
let web3HomeProvider;
let web3ForeignProvider;
@@ -88,45 +106,35 @@ contract("Cross-chain", (accounts) => {
const ethersForeignProvider = new ethers.providers.StaticJsonRpcProvider(foreignRpcUrl);
const ethersForeignSigner = ethersForeignProvider.getSigner();
- const ethersHomeSigner = new ethers.providers.StaticJsonRpcProvider(homeRpcUrl).getSigner();
+ const ethersHomeProvider = new ethers.providers.StaticJsonRpcProvider(homeRpcUrl);
+ const ethersHomeSigner = ethersHomeProvider.getSigner();
+ // const ethersHomeSigner = new ethers.providers.StaticJsonRpcProvider(homeRpcUrl).getSigner();
const ethersForeignSigner2 = new ethers.providers.StaticJsonRpcProvider(foreignRpcUrl).getSigner(1);
const ethersHomeSigner2 = new ethers.providers.StaticJsonRpcProvider(homeRpcUrl).getSigner(1);
- async function setForeignBridgeData(foreignColonyBridgeForColony) {
- const bridge = new ethers.Contract(foreignColonyBridge.address, WormholeBridgeForColony.abi, ethersForeignSigner);
-
- let tx = await bridge.setColonyBridgeAddress(foreignChainId, foreignColonyBridge.address);
- await tx.wait();
- tx = await bridge.setColonyBridgeAddress(homeChainId, homeColonyBridge.address);
- await tx.wait();
-
- tx = await bridge.setColonyNetworkAddress(foreignColonyNetwork.address);
- await tx.wait();
-
- tx = await foreignMetacolony.setColonyBridgeAddress(foreignColonyBridgeForColony);
- await tx.wait();
- }
-
- async function setHomeBridgeData(homeColonyBridgeAddressForColony) {
- const bridge = new ethers.Contract(homeColonyBridge.address, WormholeBridgeForColony.abi, ethersHomeSigner);
-
- let tx = await bridge.setColonyBridgeAddress(foreignChainId, foreignColonyBridge.address);
- await tx.wait();
- tx = await bridge.setColonyBridgeAddress(homeChainId, homeColonyBridge.address);
- await tx.wait();
-
- tx = await bridge.setColonyNetworkAddress(homeColonyNetwork.address);
- await tx.wait();
+ before(async () => {
+ homeChainId = await ethersHomeSigner.provider.send("eth_chainId", []);
+ homeChainId = ethers.BigNumber.from(homeChainId).toHexString();
+ foreignChainId = await ethersForeignSigner.provider.send("eth_chainId", []);
+ foreignChainId = ethers.BigNumber.from(foreignChainId).toHexString();
- tx = await homeMetacolony.setColonyBridgeAddress(homeColonyBridgeAddressForColony);
- await tx.wait();
- }
+ // We need to deploy the network to the other chain
+ try {
+ await exec(
+ `CHAIN_ID=${
+ process.env.HARDHAT_FOREIGN === "true" ? parseInt(homeChainId, 16) : parseInt(foreignChainId, 16)
+ } npx hardhat deploy --network development2`,
+ );
+ } catch (err) {
+ console.log(err);
+ process.exit(1);
+ }
- before(async () => {
await exec(`PORT=${FOREIGN_PORT} bash ./scripts/setup-foreign-chain.sh`);
- ({ guardianSpy, resetRelayer, gnosisSafe, zodiacBridge, homeBridge, foreignBridge, foreignColonyBridge, homeColonyBridge } = await setupBridging(
+ ({ guardianSpy, resetRelayer, gnosisSafe, zodiacBridge, homeBridge, foreignBridge, remoteColonyBridge, homeColonyBridge } = await setupBridging(
homeRpcUrl,
- foreignRpcUrl,
+ [foreignRpcUrl],
+ true,
));
// Add bridge to the foreign colony network
@@ -138,36 +146,28 @@ contract("Cross-chain", (accounts) => {
homeChainId = await ethersHomeSigner.provider.send("eth_chainId", []);
wormholeHomeChainId = evmChainIdToWormholeChainId(homeChainId);
- // const foreignNetworkId = await ethersForeignSigner.provider.send("net_version", []);
- foreignChainId = await ethersForeignSigner.provider.send("eth_chainId", []);
- wormholeForeignChainId = evmChainIdToWormholeChainId(foreignChainId);
-
- // Deploy colonyNetwork to whichever chain truffle hasn't already deployed to.
- try {
- const nonHardhatChainId = process.env.HARDHAT_FOREIGN === "true" ? homeChainId : foreignChainId;
-
- await exec(`CHAIN_ID=${parseInt(nonHardhatChainId, 16)} npx hardhat deploy --network development2`);
- } catch (err) {
- console.log(err);
- process.exit(1);
- }
-
// 0x539 is the chain id used by truffle by default (regardless of networkid), and if
// we see it in our tests that's the coverage chain, which builds the contract artifacts
// in to a different location. If we see another chain id, we assume it's non-coverage
// truffle and look for the build artifacts in the normal place.
- const homeEtherRouterAddress = (await EtherRouter.deployed()).address;
- homeColonyNetwork = await new ethers.Contract(homeEtherRouterAddress, IColonyNetwork.abi, ethersHomeSigner);
+ // const homeEtherRouterAddress = (await EtherRouter.deployed()).address;
+ homeColonyNetwork = await new ethers.Contract(NETWORK_ADDRESS, IColonyNetwork.abi, ethersHomeSigner);
- const foreignEtherRouterAddress = homeEtherRouterAddress;
- foreignColonyNetwork = await new ethers.Contract(foreignEtherRouterAddress, IColonyNetwork.abi, ethersForeignSigner);
+ // const foreignEtherRouterAddress = homeEtherRouterAddress;
+ remoteColonyNetwork = await new ethers.Contract(NETWORK_ADDRESS, ProxyColonyNetwork.abi, ethersForeignSigner);
});
beforeEach(async () => {
web3HomeProvider = new web3.eth.providers.HttpProvider(ethersHomeSigner.provider.connection.url);
web3ForeignProvider = new web3.eth.providers.HttpProvider(ethersForeignSigner.provider.connection.url);
+ if (homeSnapshotId) {
+ await revert(web3HomeProvider, homeSnapshotId);
+ await revert(web3ForeignProvider, foreignSnapshotId);
+ await resetRelayer();
+ }
+
homeSnapshotId = await snapshot(web3HomeProvider);
foreignSnapshotId = await snapshot(web3ForeignProvider);
guardianSpy.reset();
@@ -177,25 +177,24 @@ contract("Cross-chain", (accounts) => {
tx = await homeBridge.setBridgeEnabled(true);
await tx.wait();
- const foreignMCAddress = await foreignColonyNetwork.getMetaColony();
- foreignMetacolony = await new ethers.Contract(foreignMCAddress, IMetaColony.abi, ethersForeignSigner);
+ const proxyMCAddress = await homeColonyNetwork.getMetaColony(); // Not a mistake - they have the same address, and .getMetaColony doesn't exist on ProxyColonyNetwork
+ proxyMetacolony = await new ethers.Contract(proxyMCAddress, IMetaColony.abi, ethersForeignSigner);
+
const homeMCAddress = await homeColonyNetwork.getMetaColony();
homeMetacolony = await new ethers.Contract(homeMCAddress, IMetaColony.abi, ethersHomeSigner);
- await setForeignBridgeData(foreignColonyBridge.address);
- await setHomeBridgeData(homeColonyBridge.address);
-
+ await setForeignBridgeData(homeColonyBridge.address, remoteColonyBridge.address, ethersHomeSigner, ethersForeignSigner);
+ await setHomeBridgeData(homeColonyBridge.address, remoteColonyBridge.address, ethersHomeSigner, ethersForeignSigner);
// Bridge over skills that have been created on the foreign chain
- const latestSkillId = await foreignColonyNetwork.getSkillCount();
- const alreadyBridged = await homeColonyNetwork.getBridgedSkillCounts(foreignChainId);
- for (let i = alreadyBridged.add(1); i <= latestSkillId; i = i.add(1)) {
- const p = guardianSpy.getPromiseForNextBridgedTransaction();
- tx = await foreignColonyNetwork.bridgeSkillIfNotMiningChain(i);
- await tx.wait();
- await p;
- }
-
+ // const latestSkillId = await remoteColonyNetwork.getSkillCount();
+ // const alreadyBridged = await homeColonyNetwork.getBridgedSkillCounts(foreignChainId);
+ // for (let i = alreadyBridged.add(1); i <= latestSkillId; i = i.add(1)) {
+ // const p = guardianSpy.getPromiseForNextBridgedTransaction();
+ // tx = await remoteColonyNetwork.bridgeSkillIfNotMiningChain(i);
+ // await tx.wait();
+ // await p;
+ // }
// Set up mining client
client = new ReputationMinerTestWrapper({
loader: contractLoader,
@@ -219,9 +218,9 @@ contract("Cross-chain", (accounts) => {
// Set up a colony on the home chain. That may or may not be the truffle chain...
homeColony = await setupColony(homeColonyNetwork);
- const p = guardianSpy.getPromiseForNextBridgedTransaction(2);
- foreignColony = await setupColony(foreignColonyNetwork);
- await p;
+ // const p = guardianSpy.getPromiseForNextBridgedTransaction(2);
+ // remoteColony = await setupColony(remoteColonyNetwork);
+ // await p;
});
async function setupColony(colonyNetworkEthers) {
@@ -240,24 +239,19 @@ contract("Cross-chain", (accounts) => {
return colony;
}
- afterEach(async () => {
- await revert(web3HomeProvider, homeSnapshotId);
- await revert(web3ForeignProvider, foreignSnapshotId);
- await resetRelayer();
- });
-
after(async () => {
await guardianSpy.close();
});
describe("administrating cross-network bridges", async () => {
it("colonyNetwork should have the same address on each chain", async () => {
- expect(homeColonyNetwork.address).to.equal(foreignColonyNetwork.address);
+ expect(homeColonyNetwork.address).to.equal(remoteColonyNetwork.address);
// Check we have colony Network there - this equality is expected because of how we set up the addresses
const homeVersionResolver = await homeColonyNetwork.getColonyVersionResolver(CURR_VERSION);
- const foreignVersionResolver = await foreignColonyNetwork.getColonyVersionResolver(CURR_VERSION);
+ const proxyColonyResolver = await remoteColonyNetwork.proxyColonyResolverAddress();
+
expect(homeVersionResolver).to.not.equal(ADDRESS_ZERO);
- expect(foreignVersionResolver).to.not.equal(ADDRESS_ZERO);
+ expect(proxyColonyResolver).to.not.equal(ADDRESS_ZERO);
});
it("colonies deployed on different chains can have same address", async () => {
@@ -283,37 +277,56 @@ contract("Cross-chain", (accounts) => {
const colonyCreationSalt = await homeColonyNetwork.getColonyCreationSalt({ blockTag: createXDeployEvent.blockNumber });
console.log("colony creation salt", colonyCreationSalt);
- // Query CreateX on other network to prove this salt being used in the Create3 pattern
- // from colonyNetwork would result in a colony at the same address
+ // Now have the colony request a deployment of a shell on the other chain.
- // This test should be replaced by one that shows the colony on the home network can request
- // a deployment on the other chain, and that the resulting address is the same. However, that
- // functionality is not implemented yet, so we do a static call to CreateX, and get the address
- // that would be created if colonyNetwork created a colony with that salt.
- const createXForeign = new ethers.Contract(CREATEX_ADDRESS, ICreateX.abi, ethersForeignProvider);
- const cnAsEr = await EtherRouterCreate3.at(homeColonyNetwork.address);
+ const p = guardianSpy.getPromiseForNextBridgedTransaction();
- const setOwnerData = cnAsEr.contract.methods.setOwner(foreignColonyNetwork.address).encodeABI();
+ const deployedColony = new ethers.Contract(colonyAddress, IColony.abi, ethersHomeSigner);
- const colonyAddressWithSalt = await createXForeign.callStatic["deployCreate3AndInit(bytes32,bytes,bytes,(uint256,uint256))"](
- colonyCreationSalt,
- EtherRouterCreate3.bytecode,
- setOwnerData,
- [0, 0],
- { from: foreignColonyNetwork.address },
- );
+ tx = await deployedColony.createProxyColony(foreignChainId, colonyCreationSalt, { gasLimit: 1000000 });
+
+ let receipt = await tx.wait();
+ const proxyRequestEvent = receipt.events.filter((e) => e.address === homeColonyNetwork.address)[0];
+ let parsed = homeColonyNetwork.interface.parseLog(proxyRequestEvent);
+ expect(parsed.name).to.equal("ProxyColonyRequested");
+ expect(parsed.args.destinationChainId.toHexString()).to.equal(foreignChainId);
+ expect(parsed.args.salt).to.equal(colonyCreationSalt);
+ expect(parsed.args.colony).to.equal(colonyAddress);
+
+ const colonyProxyRequestEvent = receipt.events.filter((e) => e.address === colonyAddress)[0];
+ parsed = homeColony.interface.parseLog(colonyProxyRequestEvent);
+ expect(parsed.name).to.equal("ProxyColonyRequested");
+ expect(parsed.args.agent).to.equal(receipt.from);
+ expect(parsed.args.destinationChainId.toHexString()).to.equal(foreignChainId);
+ expect(parsed.args.salt).to.equal(colonyCreationSalt);
+
+ receipt = await p;
+
+ const proxyDeployedEvent = receipt.logs.filter((e) => e.address === remoteColonyNetwork.address)[0];
+ parsed = remoteColonyNetwork.interface.parseLog(proxyDeployedEvent);
+ expect(parsed.name).to.equal("ProxyColonyDeployed");
+ expect(parsed.args.proxyColony).to.equal(deployedColony.address);
+
+ // Did we deploy a shell colony on the foreign chain at the right address? Should have EtherRouter code...
+ const code = await ethersForeignProvider.getCode(deployedColony.address);
+ const codeExpected = await ethersHomeProvider.getCode(deployedColony.address);
+ expect(code).to.equal(codeExpected);
+
+ const colonyAsEtherRouter = new ethers.Contract(deployedColony.address, EtherRouter.abi, ethersForeignSigner);
+ const resolverAddress = await colonyAsEtherRouter.resolver();
+
+ const expectedResolver = await remoteColonyNetwork.proxyColonyResolverAddress();
+
+ expect(resolverAddress).to.equal(expectedResolver);
+ });
- expect(colonyAddressWithSalt).to.equal(colonyAddress);
+ it("colonies can't deploy proxies that aren't for themselves", async () => {
+ const colony = await setupColony(homeColonyNetwork);
- // Demonstrate that another address using that salt would not get the same address
- const otherAddress = await createXForeign.callStatic["deployCreate3AndInit(bytes32,bytes,bytes,(uint256,uint256))"](
- colonyCreationSalt,
- EtherRouterCreate3.bytecode,
- setOwnerData,
- [0, 0],
- );
+ const deployedColony = new ethers.Contract(colony.address, IColony.abi, ethersHomeSigner);
- expect(otherAddress).to.not.equal(colonyAddress);
+ const tx = await deployedColony.createProxyColony(foreignChainId, ethers.constants.HashZero, { gasLimit: 1000000 });
+ checkErrorRevertEthers(tx.wait(), "colony-network-wrong-salt");
});
it("bridge data can be queried", async () => {
@@ -323,23 +336,91 @@ contract("Cross-chain", (accounts) => {
const networkAddress = await homeColonyBridge.colonyNetwork();
expect(networkAddress).to.equal(homeColonyNetwork.address);
- const foreignColonyBridgeAddress = await homeColonyBridge.getColonyBridgeAddress(foreignChainId);
- expect(foreignColonyBridgeAddress).to.equal(foreignColonyBridge.address);
+ const remoteColonyBridgeAddress = await homeColonyBridge.getColonyBridgeAddress(foreignChainId);
+ expect(remoteColonyBridgeAddress).to.equal(remoteColonyBridge.address);
});
- it("setColonyBridgeAddress on Network can only be called by the metacolony", async () => {
- const tx = await foreignColonyNetwork.setColonyBridgeAddress(foreignColonyBridge.address, { gasLimit: 1000000 });
+ it("setColonyBridgeAddress on proxy Network can be called directly by the owner (and not a random address)", async () => {
+ const owner = await remoteColonyNetwork.owner();
+ expect(await remoteColonyNetwork.signer.getAddress()).to.equal(owner);
+ let tx = await remoteColonyNetwork.setColonyBridgeAddress(remoteColonyBridge.address, { gasLimit: 1000000 });
+ await tx.wait();
+
+ const remoteColonyNetwork2 = new ethers.Contract(remoteColonyNetwork.address, IColonyNetwork.abi, ethersForeignSigner2);
+ expect(await remoteColonyNetwork2.signer.getAddress()).to.not.equal(owner);
+ tx = await remoteColonyNetwork2.setColonyBridgeAddress(remoteColonyBridge.address, { gasLimit: 1000000, from: accounts[1] });
+ await checkErrorRevertEthers(tx.wait(), "colony-network-caller-must-be-owner-or-bridge");
+ });
+
+ it("setColonyBridgeAddress on Home Network can only be called by the meta colony", async () => {
+ const tx = await homeColonyNetwork.setColonyBridgeAddress(homeColonyBridge.address, { gasLimit: 1000000 });
+ await checkErrorRevertEthers(tx.wait(), "colony-caller-must-be-meta-colony");
+ });
+
+ it("multicallProxyNetwork can only be called through the metacolony", async () => {
+ const payload = homeColonyNetwork.interface.encodeFunctionData("setColonyBridgeAddress", [ADDRESS_ZERO]);
+ let tx = await homeColonyNetwork.createColonyForFrontend(ADDRESS_ZERO, "A", "A", 18, CURR_VERSION, "", "");
+ await tx.wait();
+
+ const colonyCount = await homeColonyNetwork.getColonyCount();
+ const colonyAddress = await homeColonyNetwork.getColony(colonyCount);
+ const fakeMetaColony = new ethers.Contract(colonyAddress, IMetaColony.abi, ethersHomeSigner);
+
+ tx = await fakeMetaColony.multicallProxyNetwork(foreignChainId, [payload], { gasLimit: 1000000 });
await checkErrorRevertEthers(tx.wait(), "colony-caller-must-be-meta-colony");
});
+ it("multicallProxyNetwork can only be called by root permissions on the metacolony", async () => {
+ const payload = remoteColonyNetwork.interface.encodeFunctionData("setColonyBridgeAddress", [ADDRESS_ZERO]);
+ const homeMetacolony2 = new ethers.Contract(homeMetacolony.address, IMetaColony.abi, ethersHomeSigner2);
+ let tx = await homeMetacolony2.multicallProxyNetwork(foreignChainId, [payload], { gasLimit: 1000000 });
+ await checkErrorRevertEthers(tx.wait(), "ds-auth-unauthorized");
+
+ // Add root permissions
+ tx = await homeMetacolony.setUserRoles(
+ 1,
+ UINT256_MAX_ETHERS,
+ accounts[1],
+ 1,
+ ethers.utils.hexZeroPad(ethers.BigNumber.from(ethers.BigNumber.from(2).pow(ROOT_ROLE)).toHexString(), 32),
+ );
+
+ await tx.wait();
+
+ // Can now call
+ const p = guardianSpy.getPromiseForNextBridgedTransaction();
+ const tx3 = await homeMetacolony2.multicallProxyNetwork(foreignChainId, [payload]);
+ await tx3.wait();
+ await p;
+
+ // Check call was successful
+ const bridgeAddressAfter = await remoteColonyNetwork.colonyBridgeAddress();
+ expect(bridgeAddressAfter).to.equal(ADDRESS_ZERO);
+
+ // Reset permissions
+ tx = await homeMetacolony.setUserRoles(1, UINT256_MAX_ETHERS, accounts[1], 1, ethers.utils.hexZeroPad("0x00", 32));
+ await tx.wait();
+ });
+
+ it("setColonyBridgeAddress on Proxy Network can be used across the bridge", async () => {
+ const bridgeAddress = await remoteColonyNetwork.colonyBridgeAddress();
+ const payload = remoteColonyNetwork.interface.encodeFunctionData("setColonyBridgeAddress", [ADDRESS_ZERO]);
+ const p = guardianSpy.getPromiseForNextBridgedTransaction();
+ const tx = await homeMetacolony.multicallProxyNetwork(foreignChainId, [payload]);
+ await tx.wait();
+ await p;
+ const bridgeAddressAfter = await remoteColonyNetwork.colonyBridgeAddress();
+ expect(bridgeAddressAfter).to.not.equal(bridgeAddress);
+ });
+
it("setColonyBridgeAddress on Metacolony can't be called by an address without root permissions", async () => {
- const foreignMetacolony2 = new ethers.Contract(foreignMetacolony.address, IColonyNetwork.abi, ethersForeignSigner2);
+ const homeMetacolony2 = new ethers.Contract(proxyMetacolony.address, IColonyNetwork.abi, ethersHomeSigner2);
- let tx = await foreignMetacolony2.setColonyBridgeAddress(ADDRESS_ZERO, { gasLimit: 1000000 });
+ let tx = await homeMetacolony2.setColonyBridgeAddress(ADDRESS_ZERO, { gasLimit: 1000000 });
await checkErrorRevertEthers(tx.wait(), "ds-auth-unauthorized");
// Add root permissions
- tx = await foreignMetacolony.setUserRoles(
+ tx = await homeMetacolony.setUserRoles(
1,
UINT256_MAX_ETHERS,
accounts[1],
@@ -349,13 +430,13 @@ contract("Cross-chain", (accounts) => {
await tx.wait();
// Can now call
- tx = await foreignMetacolony2.setColonyBridgeAddress(ADDRESS_ZERO, {
+ tx = await homeMetacolony2.setColonyBridgeAddress(ADDRESS_ZERO, {
gasLimit: 1000000,
});
await tx.wait();
// Reset permissions
- tx = await foreignMetacolony.setUserRoles(1, UINT256_MAX_ETHERS, accounts[1], 1, ethers.utils.hexZeroPad("0x00", 32));
+ tx = await proxyMetacolony.setUserRoles(1, UINT256_MAX_ETHERS, accounts[1], 1, ethers.utils.hexZeroPad("0x00", 32));
await tx.wait();
});
@@ -366,22 +447,6 @@ contract("Cross-chain", (accounts) => {
await checkErrorRevertEthers(tx.wait(), "colony-bridge-chainid-too-large");
});
- it("updating the bridge for a chain does not reset the bridged skill count", async () => {
- const countBefore = await homeColonyNetwork.getBridgedSkillCounts(foreignChainId);
- const tx = await homeMetacolony.setColonyBridgeAddress(ADDRESS_ZERO);
- await tx.wait();
-
- const countAfter = await homeColonyNetwork.getBridgedSkillCounts(foreignChainId);
- expect(countAfter).to.not.equal(0);
- expect(countAfter.sub(countBefore).toNumber()).to.equal(0);
- });
-
- it("the bridged skill count has a sensible default", async () => {
- const unsetChainId = ethers.BigNumber.from(123456789);
- const count = await homeColonyNetwork.getBridgedSkillCounts(unsetChainId);
- expect(count.toString()).to.equal(unsetChainId.shl(128).toString());
- });
-
it("only owners can set properties on the ColonyBridge", async () => {
let tx = await homeColonyBridge.connect(ethersHomeSigner2).setColonyNetworkAddress(ADDRESS_ZERO, { gasLimit: 1000000 });
await checkErrorRevertEthers(tx.wait(), "ds-auth-unauthorized");
@@ -438,7 +503,6 @@ contract("Cross-chain", (accounts) => {
// So 'just' call that on the colony...
- console.log("tx to home bridge address:", homeBridge.address);
const tx = await homeColony.makeArbitraryTransaction(homeBridge.address, txDataToBeSentToAMB);
await tx.wait();
await p;
@@ -450,958 +514,948 @@ contract("Cross-chain", (accounts) => {
});
});
- describe("when adding skills on another chain", async () => {
- it("can create a skill on another chain and it's reflected on the home chain", async () => {
- // See skills on home chain
- const beforeCount = await homeColonyNetwork.getBridgedSkillCounts("0x0fd5c9ed");
+ describe("collecting and paying out tokens on another chain", async () => {
+ let foreignToken;
+ let colony;
+ beforeEach(async () => {
+ colony = await setupColony(homeColonyNetwork);
+
+ const events = await homeColonyNetwork.queryFilter(homeColonyNetwork.filters.ColonyAdded());
+ // homeColonyNetwork.fil
+ // Deploy a proxy colony on the foreign network
+
+ const colonyCreationSalt = await homeColonyNetwork.getColonyCreationSalt({ blockTag: events[events.length - 1].blockNumber });
const p = guardianSpy.getPromiseForNextBridgedTransaction();
- // Create a skill on foreign chain
- // await foreignColony.addDomain(1);
- const foreignBeforeCount = await foreignColonyNetwork.getSkillCount();
- const tx = await foreignColony["addDomain(uint256,uint256,uint256)"](1, UINT256_MAX_ETHERS, 1);
+ const tx = await colony.createProxyColony(foreignChainId, colonyCreationSalt, { gasLimit: 1000000 });
await tx.wait();
- const foreignAfterCount = await foreignColonyNetwork.getSkillCount();
- expect(foreignBeforeCount.add(1).toHexString()).to.equal(foreignAfterCount.toHexString());
await p;
+ proxyColony = new ethers.Contract(colony.address, ProxyColony.abi, ethersForeignSigner);
+ // Deploy a token on the foreign network
- // Check reflected on home chain
- const afterCount = await homeColonyNetwork.getBridgedSkillCounts("0x0fd5c9ed");
- expect(beforeCount.add(1).toHexString()).to.equal(afterCount.toHexString());
- });
+ const tokenFactory = new ethers.ContractFactory(MetaTxToken.abi, MetaTxToken.bytecode, ethersForeignSigner);
+ foreignToken = await tokenFactory.deploy("Test Token", "TT", 18);
+ await (await foreignToken.unlock()).wait();
- it("addSkillFromBridge cannot be called by a non-bridge address", async () => {
- const tx = await homeColonyNetwork.addSkillFromBridge(0, 0, {
- gasLimit: 1000000,
- });
- await checkErrorRevertEthers(tx.wait(), "colony-network-caller-must-be-colony-bridge");
+ await (await colony.setArbitrationRole(1, UINT256_MAX_ETHERS, accounts[0], 1, true)).wait();
+ await (await colony.setFundingRole(1, UINT256_MAX_ETHERS, accounts[0], 1, true)).wait();
});
- it("addPendingSkill doesn't create skills that haven't been bridged", async () => {
- const homeSkillCount = await homeColonyNetwork.getBridgedSkillCounts(foreignChainId);
- const tx = await homeColonyNetwork.addPendingSkill(homeSkillCount.add(1), { gasLimit: 1000000 });
- await checkErrorRevertEthers(tx.wait(), "colony-network-no-such-bridged-skill");
- });
+ it("Can track tokens received on the foreign chain", async () => {
+ const tokenAmount = ethers.utils.parseEther("100");
- it("if a skill is bridged out-of-order, it's added to the pending mapping", async () => {
- guardianSpy.skipCount = 1;
- // Create a skill on the foreign chain
- let tx = await foreignColony["addDomain(uint256,uint256,uint256)"](1, UINT256_MAX_ETHERS, 1);
+ let tx = await foreignToken["mint(address,uint256)"](proxyColony.address, tokenAmount);
await tx.wait();
- await guardianSpy.waitUntilSkipped();
+ // Claim on the foreign chain
- const foreignDomain = await foreignColony.getDomain(1);
-
- let p = guardianSpy.getPromiseForNextBridgedTransaction();
+ const p = guardianSpy.getPromiseForNextBridgedTransaction();
- // Create another skill on the foreign chain
- // Bridge the latter without bridging the former
- tx = await foreignColony["addDomain(uint256,uint256,uint256)"](1, UINT256_MAX_ETHERS, 1);
+ tx = await proxyColony.claimColonyFunds(foreignToken.address);
await tx.wait();
- const foreignSkillCount = await foreignColonyNetwork.getSkillCount();
- await p;
+ const receipt = await p;
+ expect(receipt.status).to.equal(1);
- // Check it's pending
- const pendingAddition = await homeColonyNetwork.getPendingSkillAddition(foreignChainId, foreignSkillCount);
+ // Check bookkeeping on the home chain
- expect(pendingAddition.toHexString()).to.equal(foreignDomain.skillId.toHexString());
+ const balance = await colony["getFundingPotBalance(uint256,uint256,address)"](1, foreignChainId, foreignToken.address);
+ expect(balance.toHexString()).to.equal(tokenAmount.toHexString());
- // Need to clean up
- p = guardianSpy.getPromiseForNextBridgedTransaction();
- tx = await foreignColonyNetwork.bridgeSkillIfNotMiningChain(foreignSkillCount.sub(1));
- await tx.wait();
- await p;
- tx = await homeColonyNetwork.addPendingSkill(foreignSkillCount, { gasLimit: 1000000 });
- await tx.wait();
+ const nonRewardPotTotal = await colony["getNonRewardPotsTotal(uint256,address)"](foreignChainId, foreignToken.address);
+ expect(nonRewardPotTotal.toHexString()).to.equal(tokenAmount.toHexString());
});
- it("if a skill is bridged out-of-order, it can be added once the earlier skills are bridged ", async () => {
- guardianSpy.skipCount = 1;
- // Create a skill on the foreign chain
- let tx = await foreignColony["addDomain(uint256,uint256,uint256)"](1, UINT256_MAX_ETHERS, 1);
+ it("Reward payout pot is respected even cross-chain", async () => {
+ const tokenAmount = ethers.utils.parseEther("100");
+
+ // Mint tokens to proxy colony on foreign chain
+ let tx = await foreignToken["mint(address,uint256)"](proxyColony.address, tokenAmount);
await tx.wait();
- await guardianSpy.waitUntilSkipped();
- let p = guardianSpy.getPromiseForNextBridgedTransaction();
- // Create another skill on the foreign chain
- // Bridge the latter without bridging the former
- tx = await foreignColony["addDomain(uint256,uint256,uint256)"](1, UINT256_MAX_ETHERS, 1);
+ // Claim tokens on foreign chain
+ const p = guardianSpy.getPromiseForNextBridgedTransaction();
+ tx = await proxyColony.claimColonyFunds(foreignToken.address);
await tx.wait();
- const foreignSkillCount = await foreignColonyNetwork.getSkillCount();
await p;
- // Try to add
- tx = await homeColonyNetwork.addPendingSkill(foreignSkillCount, { gasLimit: 1000000 });
- await checkErrorRevertEthers(tx.wait(), "colony-network-not-next-bridged-skill");
+ // Move 30 tokens in to the reward pot 0
+ await (
+ await colony["moveFundsBetweenPots(uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,address)"](
+ 1,
+ UINT256_MAX_ETHERS,
+ 1,
+ UINT256_MAX_ETHERS,
+ UINT256_MAX_ETHERS,
+ 1,
+ 0,
+ ethers.utils.parseEther("30"),
+ foreignChainId,
+ foreignToken.address,
+ )
+ ).wait();
+
+ await colony["addDomain(uint256,uint256,uint256)"](1, UINT256_MAX_ETHERS, 1);
+
+ // Try and move tokens from root domain that are in the reward pot
+ const domain1 = await colony.getDomain(1);
+ const domain2 = await colony.getDomain(2);
+
+ tx = await colony["moveFundsBetweenPots(uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,address)"](
+ 1,
+ UINT256_MAX_ETHERS,
+ 1,
+ UINT256_MAX_ETHERS,
+ 0,
+ domain1.fundingPotId,
+ domain2.fundingPotId,
+ ethers.utils.parseEther("80"),
+ foreignChainId,
+ foreignToken.address,
+ { gasLimit: 1000000 },
+ );
+ await checkErrorRevertEthers(tx.wait(), PANIC.ARITHMETHIC_OVERFLOW);
+ });
- // Bridge the next skill
- p = guardianSpy.getPromiseForNextBridgedTransaction();
- tx = await foreignColonyNetwork.bridgeSkillIfNotMiningChain(foreignSkillCount.sub(1));
+ it("Can claim tokens received on foreign chain via cross-chain request (manually)", async () => {
+ const tokenAmount = ethers.utils.parseEther("100");
+
+ let tx = await foreignToken["mint(address,uint256)"](proxyColony.address, tokenAmount);
await tx.wait();
- await p;
- // Add the pending skill
- tx = await homeColonyNetwork.addPendingSkill(foreignSkillCount, { gasLimit: 1000000 });
+ // Claim on the foreign chain
+ const p = guardianSpy.getPromiseForNextBridgedTransaction(2);
+ // One bridged transaction will be the request across, one will be reporting what was claimed back
+
+ const payload = proxyColony.interface.encodeFunctionData("claimColonyFunds", [foreignToken.address]);
+ tx = await colony.makeProxyArbitraryTransaction(foreignChainId, proxyColony.address, payload);
await tx.wait();
+ await p;
- // Check it was added
- const homeSkillCount = await homeColonyNetwork.getBridgedSkillCounts(foreignChainId);
- expect(homeSkillCount.toHexString()).to.equal(foreignSkillCount.toHexString());
+ // Check bookkeeping on the home chain
- // And removed from pending
- const pendingAddition = await homeColonyNetwork.getPendingSkillAddition(foreignChainId, foreignSkillCount);
- expect(pendingAddition.toHexString()).to.equal("0x00");
+ const balance = await colony["getFundingPotBalance(uint256,uint256,address)"](1, foreignChainId, foreignToken.address);
+ expect(balance.toHexString()).to.equal(tokenAmount.toHexString());
});
- it("if a skill that was pending is repeatedly bridged, the resuling transaction fails after the first time", async () => {
- guardianSpy.skipCount = 1;
- // Create a skill on the foreign chain
- let tx = await foreignColony["addDomain(uint256,uint256,uint256)"](1, UINT256_MAX_ETHERS, 1);
- await tx.wait();
- await guardianSpy.waitUntilSkipped();
+ it("Can claim tokens received on foreign chain via cross-chain request (via claimColonyFunds)", async () => {
+ const tokenAmount = ethers.utils.parseEther("100");
- let p = guardianSpy.getPromiseForNextBridgedTransaction();
- // Create another skill on the foreign chain
- // Bridge the latter without bridging the former
- tx = await foreignColony["addDomain(uint256,uint256,uint256)"](1, UINT256_MAX_ETHERS, 1);
+ let tx = await foreignToken["mint(address,uint256)"](proxyColony.address, tokenAmount);
await tx.wait();
- const foreignSkillCount = await foreignColonyNetwork.getSkillCount();
- await p;
- // Try to add
- tx = await homeColonyNetwork.addPendingSkill(foreignSkillCount, { gasLimit: 1000000 });
- await checkErrorRevertEthers(tx.wait(), "colony-network-not-next-bridged-skill");
+ // Claim on the foreign chain
+ const p = guardianSpy.getPromiseForNextBridgedTransaction(2);
+ // One bridged transaction will be the request across, one will be reporting what was claimed back
- // Bridge the next skill
- p = guardianSpy.getPromiseForNextBridgedTransaction();
- tx = await foreignColonyNetwork.bridgeSkillIfNotMiningChain(foreignSkillCount.sub(1));
+ tx = await colony["claimColonyFunds(uint256,address)"](foreignChainId, foreignToken.address);
await tx.wait();
await p;
- // Add the pending skill
- tx = await homeColonyNetwork.addPendingSkill(foreignSkillCount, { gasLimit: 1000000 });
+ // Check bookkeeping on the home chain
+
+ const balance = await colony["getFundingPotBalance(uint256,uint256,address)"](1, foreignChainId, foreignToken.address);
+ expect(balance.toHexString()).to.equal(tokenAmount.toHexString());
+ });
+
+ it("Can multicall claimColonyFunds and receive both tokens", async () => {
+ const tokenFactory = new ethers.ContractFactory(Token.abi, Token.bytecode, ethersForeignSigner);
+ const foreignToken2 = await tokenFactory.deploy("Test Token", "TT", 18);
+ await (await foreignToken2.unlock()).wait();
+ const tokenAmount = ethers.utils.parseEther("100");
+ let tx = await foreignToken["mint(address,uint256)"](proxyColony.address, tokenAmount);
+ await tx.wait();
+ tx = await foreignToken2["mint(address,uint256)"](proxyColony.address, tokenAmount);
await tx.wait();
- // Adding again doesn't work
- tx = await homeColonyNetwork.addPendingSkill(foreignSkillCount, { gasLimit: 1000000 });
- await checkErrorRevertEthers(tx.wait(), "colony-network-not-next-bridged-skill");
+ const p = guardianSpy.getPromiseForNextBridgedTransaction(4);
+
+ const call1 = colony.interface.encodeFunctionData("claimColonyFunds(uint256,address)", [foreignChainId, foreignToken.address]);
+ const call2 = colony.interface.encodeFunctionData("claimColonyFunds(uint256,address)", [foreignChainId, foreignToken2.address]);
+ tx = await colony.multicall([call1, call2]);
- // And bridging again doesn't work
- p = guardianSpy.getPromiseForNextBridgedTransaction();
- tx = await foreignColonyNetwork.bridgeSkillIfNotMiningChain(foreignSkillCount);
await tx.wait();
await p;
- const pendingAddition = await homeColonyNetwork.getPendingSkillAddition(foreignChainId, foreignSkillCount);
- expect(pendingAddition.toHexString()).to.equal("0x00");
+ const balance1 = await colony["getFundingPotBalance(uint256,uint256,address)"](1, foreignChainId, foreignToken.address);
+ expect(balance1.toHexString()).to.equal(tokenAmount.toHexString());
- const homeSkillCount = await homeColonyNetwork.getBridgedSkillCounts(foreignChainId);
- expect(homeSkillCount.toHexString()).to.equal(foreignSkillCount.toHexString());
+ const balance2 = await colony["getFundingPotBalance(uint256,uint256,address)"](1, foreignChainId, foreignToken2.address);
+ expect(balance2.toHexString()).to.equal(tokenAmount.toHexString());
});
- it("can't bridge a skill that doesn't exist", async () => {
- const skillCount = await foreignColonyNetwork.getSkillCount();
- const nonExistentSkillId = skillCount.add(10000000);
- const tx = await foreignColonyNetwork.bridgeSkillIfNotMiningChain(nonExistentSkillId, {
- gasLimit: 1000000,
- });
- await checkErrorRevertEthers(tx.wait(), "colony-invalid-skill-id");
- });
+ it("Can claim tokens received on foreign chain via metatransaction", async () => {
+ const tokenAmount = ethers.utils.parseEther("100");
- it("if bridge is broken, bridging skill transaction doesn't revert (allowing e.g. domains to be created)", async () => {
- let tx = await foreignBridge.setBridgeEnabled(false);
+ let tx = await foreignToken["mint(address,uint256)"](proxyColony.address, tokenAmount);
await tx.wait();
- const skillCount = await foreignColonyNetwork.getSkillCount();
-
- tx = await foreignColonyNetwork.bridgeSkillIfNotMiningChain(skillCount, {
- gasLimit: 1000000,
- });
- let receipt = await tx.wait();
- expect(receipt.status).to.equal(1);
-
- tx = await foreignColony["addDomain(uint256,uint256,uint256)"](1, UINT256_MAX_ETHERS, 1);
- receipt = await tx.wait();
-
- let events = receipt.logs.map(function (log) {
- try {
- return foreignColonyNetwork.interface.parseLog(log);
- } catch (e) {
- // Return nothing
- }
- return null;
- });
- events = events.filter((x) => x != null && x.eventFragment.name === "SkillCreationStored");
- expect(events.length).to.equal(1);
- const event = events[0];
- expect(event.args[0].toString()).to.equal(skillCount.add(1).toString());
- });
- it("colony root local skill structures end up the same on both chains", async () => {
- const homeColonyRootLocalSkillId = await homeColony.getRootLocalSkill();
- let homeColonyRootLocalSkill = await homeColonyNetwork.getSkill(homeColonyRootLocalSkillId);
+ const metatransactionNonceBefore = await proxyColony.getMetatransactionNonce(accounts[1]);
- const foreignColonyRootLocalSkillId = await foreignColony.getRootLocalSkill();
- let foreignColonyRootLocalSkill = await foreignColonyNetwork.getSkill(foreignColonyRootLocalSkillId);
+ // Claim on the foreign chain via metatransaction
+ const p = guardianSpy.getPromiseForNextBridgedTransaction();
- expect(homeColonyRootLocalSkill.nParents.toString()).to.equal(foreignColonyRootLocalSkill.nParents.toString());
- expect(homeColonyRootLocalSkill.nChildren.toString()).to.equal(foreignColonyRootLocalSkill.nChildren.toString());
+ const payload = proxyColony.interface.encodeFunctionData("claimColonyFunds", [foreignToken.address]);
- let tx = await homeColony.addLocalSkill();
- await tx.wait();
+ const { r, s, v } = await getMetaTransactionParameters(payload, accounts[1], proxyColony.address, foreignChainId);
- const p = guardianSpy.getPromiseForNextBridgedTransaction();
- tx = await foreignColony.addLocalSkill();
+ tx = await proxyColony.executeMetaTransaction(accounts[1], payload, r, s, v, { from: accounts[0] });
await tx.wait();
await p;
- homeColonyRootLocalSkill = await homeColonyNetwork.getSkill(homeColonyRootLocalSkillId);
- foreignColonyRootLocalSkill = await foreignColonyNetwork.getSkill(foreignColonyRootLocalSkillId);
-
- expect(homeColonyRootLocalSkill.nParents.toString()).to.equal(foreignColonyRootLocalSkill.nParents.toString());
- expect(homeColonyRootLocalSkill.nChildren.toString()).to.equal(foreignColonyRootLocalSkill.nChildren.toString());
- let zeroSkill = await foreignColonyNetwork.getSkill(ethers.BigNumber.from(foreignChainId).mul(ethers.BigNumber.from(2).pow(128)));
- expect(zeroSkill.nChildren.toNumber()).to.equal(0);
+ // Check bookkeeping on the home chain
+ const balance = await colony["getFundingPotBalance(uint256,uint256,address)"](1, foreignChainId, foreignToken.address);
+ expect(balance.toHexString()).to.equal(tokenAmount.toHexString());
- zeroSkill = await homeColonyNetwork.getSkill(ethers.BigNumber.from(foreignChainId).mul(ethers.BigNumber.from(2).pow(128)));
- expect(zeroSkill.nChildren.toNumber()).to.equal(0);
-
- zeroSkill = await homeColonyNetwork.getSkill(0);
- expect(zeroSkill.nChildren.toNumber()).to.equal(0);
+ // Check nonce incremented
+ const metatransactionNonceAfter = await proxyColony.getMetatransactionNonce(accounts[1]);
+ expect(metatransactionNonceAfter.toHexString()).to.equal(metatransactionNonceBefore.add(1).toHexString());
});
- });
- describe("while earning reputation on another chain", async () => {
- it("reputation awards are ultimately reflected", async () => {
- let p = guardianSpy.getPromiseForNextBridgedTransaction();
- // Emit reputation
- await foreignColony.emitDomainReputationReward(1, accounts[0], "0x1337");
- // See that it's bridged to the inactive log
- await p;
- const logAddress = await homeColonyNetwork.getReputationMiningCycle(false);
- const reputationMiningCycleInactive = new ethers.Contract(logAddress, IReputationMiningCycle.abi, ethersHomeSigner);
-
- const len = await reputationMiningCycleInactive.getReputationUpdateLogLength();
+ it("Can track native tokens received on foreign chains", async () => {
+ const tokenAmount = ethers.utils.parseEther("1");
- const entry = await reputationMiningCycleInactive.getReputationUpdateLogEntry(len.sub(1));
+ await ethersForeignSigner.sendTransaction({
+ to: proxyColony.address,
+ value: tokenAmount,
+ });
- expect(entry.amount.toHexString()).to.equal("0x1337");
- expect(entry.user).to.equal(accounts[0]);
- expect(entry.colony).to.equal(foreignColony.address);
+ // Claim on foreign chain
+ const p = guardianSpy.getPromiseForNextBridgedTransaction();
- const domain = await foreignColony.getDomain(1);
+ const tx = await proxyColony.claimColonyFunds(ADDRESS_ZERO);
+ await tx.wait();
- expect(entry.skillId.toHexString()).to.equal(domain.skillId.toHexString());
+ const receipt = await p;
+ expect(receipt.status).to.equal(1);
- // Advance mining cycle twice
- await forwardTime(MINING_CYCLE_DURATION + CHALLENGE_RESPONSE_WINDOW_DURATION, undefined, web3HomeProvider);
- await client.addLogContentsToReputationTree();
- await client.submitRootHash();
- await client.confirmNewHash();
+ // Check bookkeeping on the home chain
- await forwardTime(MINING_CYCLE_DURATION + CHALLENGE_RESPONSE_WINDOW_DURATION, undefined, web3HomeProvider);
- await client.addLogContentsToReputationTree();
- await client.submitRootHash();
- await client.confirmNewHash();
+ const balance = await colony["getFundingPotBalance(uint256,uint256,address)"](1, foreignChainId, ADDRESS_ZERO);
+ expect(balance.toHexString()).to.equal(tokenAmount.toHexString());
+ });
- // Check in state
- const key = await ReputationMinerTestWrapper.getKey(foreignColony.address, entry.skillId, accounts[0]);
- expect(client.reputations[key]).to.not.equal(undefined);
- expect(ethers.BigNumber.from(client.reputations[key].slice(0, 66)).toHexString()).to.equal("0x1337");
+ it("Can track tokens sent on the foreign chain", async () => {
+ const tokenAmount = ethers.utils.parseEther("100");
- // Bridge it
+ let tx = await foreignToken["mint(address,uint256)"](proxyColony.address, tokenAmount);
+ await tx.wait();
- p = guardianSpy.getPromiseForNextBridgedTransaction();
- const tx = await homeColonyNetwork.bridgeCurrentRootHash(foreignChainId);
+ // Claim on the foreign chain
+ let p = guardianSpy.getPromiseForNextBridgedTransaction();
+ tx = await proxyColony.claimColonyFunds(foreignToken.address);
await tx.wait();
await p;
- // Check state bridged to host chain
- const foreignChainRootHash = await foreignColonyNetwork.getReputationRootHash();
- const foreignNLeaves = await foreignColonyNetwork.getReputationRootHashNNodes();
- const homeChainRootHash = await homeColonyNetwork.getReputationRootHash();
- const homeNLeaves = await homeColonyNetwork.getReputationRootHashNNodes();
+ // Make a payment that pays out 30
- expect(foreignChainRootHash).to.equal(homeChainRootHash);
- expect(homeNLeaves.toHexString()).to.equal(foreignNLeaves.toHexString());
- });
-
- it("if bridge disabled, reputation emissions are stored to be reemitted later", async () => {
- let tx = await foreignBridge.setBridgeEnabled(false);
- await tx.wait();
- const bridgedReputationUpdateCountBefore = await foreignColonyNetwork.getBridgedReputationUpdateCount(foreignChainId, foreignColony.address);
- tx = await foreignColony.emitDomainReputationReward(1, accounts[0], "0x1337");
+ const paymentAmount = ethers.utils.parseEther("30");
+ tx = await colony.makeExpenditure(1, UINT256_MAX_ETHERS, 1);
await tx.wait();
+ const expenditureId = await colony.getExpenditureCount();
- // See it was stored for later
- const bridgedReputationUpdateCountAfter = await foreignColonyNetwork.getBridgedReputationUpdateCount(foreignChainId, foreignColony.address);
- expect(bridgedReputationUpdateCountAfter.sub(bridgedReputationUpdateCountBefore).toNumber()).to.equal(1);
- });
-
- it("if bridge disabled, cannot bridge current state", async () => {
- let tx = await homeBridge.setBridgeEnabled(false);
+ tx = await colony.setExpenditureRecipient(expenditureId, 1, accounts[0]);
await tx.wait();
- tx = await homeColonyNetwork.bridgeCurrentRootHash(foreignChainId, { gasLimit: 1000000 });
- await checkErrorRevertEthers(tx.wait(), "colony-mining-bridge-call-failed");
- });
- it("if bridge not set, cannot bridge current state", async () => {
- let tx = await homeMetacolony.setColonyBridgeAddress(ADDRESS_ZERO);
+ tx = await colony["setExpenditurePayout(uint256,uint256,uint256,uint256,uint256,address,uint256)"](
+ 1,
+ UINT256_MAX_ETHERS,
+ expenditureId,
+ 1,
+ foreignChainId,
+ foreignToken.address,
+ paymentAmount,
+ );
await tx.wait();
- tx = await homeColonyNetwork.bridgeCurrentRootHash(foreignChainId, { gasLimit: 1000000 });
- await checkErrorRevertEthers(tx.wait(), "colony-network-bridge-not-set");
- });
- it("if bridge unknown, cannot bridge current state", async () => {
- const tx = await homeColonyNetwork.bridgeCurrentRootHash(ADDRESS_ZERO, { gasLimit: 1000000 });
- await checkErrorRevertEthers(tx.wait(), "colony-bridge-not-known-chain");
- });
+ const domain1 = await colony.getDomain(1);
+ const expenditure = await colony.getExpenditure(expenditureId);
- it("stored reputation emissions can be emitted later", async () => {
- let tx = await foreignBridge.setBridgeEnabled(false);
- await tx.wait();
- tx = await foreignColony.emitDomainReputationReward(1, accounts[0], "0x1338");
+ tx = await colony["moveFundsBetweenPots(uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,address)"](
+ 1,
+ UINT256_MAX_ETHERS,
+ 1,
+ UINT256_MAX_ETHERS,
+ UINT256_MAX_ETHERS,
+ domain1.fundingPotId,
+ expenditure.fundingPotId,
+ paymentAmount,
+ foreignChainId,
+ foreignToken.address,
+ );
await tx.wait();
-
- const bridgedReputationUpdateCount = await foreignColonyNetwork.getBridgedReputationUpdateCount(foreignChainId, foreignColony.address);
-
- tx = await foreignBridge.setBridgeEnabled(true);
+ tx = await colony.finalizeExpenditure(expenditureId);
await tx.wait();
- const p = guardianSpy.getPromiseForNextBridgedTransaction();
- tx = await foreignColonyNetwork.bridgePendingReputationUpdate(foreignColony.address, bridgedReputationUpdateCount);
+ p = guardianSpy.getPromiseForNextBridgedTransaction();
+ tx = await colony["claimExpenditurePayout(uint256,uint256,uint256,address)"](expenditureId, 1, foreignChainId, foreignToken.address);
await tx.wait();
-
await p;
+ // Check bookkeeping on the home chain
- // See that it's bridged to the inactive log
- const logAddress = await homeColonyNetwork.getReputationMiningCycle(false);
- const reputationMiningCycleInactive = await new ethers.Contract(logAddress, IReputationMiningCycle.abi, ethersHomeSigner);
-
- const len = await reputationMiningCycleInactive.getReputationUpdateLogLength();
-
- const entry = await reputationMiningCycleInactive.getReputationUpdateLogEntry(len.sub(1));
+ const balance1 = await colony["getFundingPotBalance(uint256,uint256,address)"](1, foreignChainId, foreignToken.address);
+ expect(balance1.toHexString()).to.equal(ethers.utils.parseEther("70").toHexString());
- expect(entry.amount.toHexString()).to.equal("0x1338");
- expect(entry.user).to.equal(accounts[0]);
- expect(entry.colony).to.equal(foreignColony.address);
+ // Check actually paid on foreign chain
+ const colonyBalance = await foreignToken.balanceOf(proxyColony.address);
+ const recipientBalance = await foreignToken.balanceOf(accounts[0]);
- const domain = await foreignColony.getDomain(1);
-
- expect(entry.skillId.toHexString()).to.equal(domain.skillId.toHexString());
+ expect(colonyBalance.toHexString()).to.equal(ethers.utils.parseEther("70").toHexString());
+ expect(recipientBalance.toHexString()).to.equal(ethers.utils.parseEther("30").sub(ethers.utils.parseEther("0.3").add(1)).toHexString());
});
- it("stored reputation emissions on the foreign chain can be bridged later, and are decayed if required", async () => {
- let tx = await foreignBridge.setBridgeEnabled(false);
+ it("Can track native tokens sent on the foreign chain", async () => {
+ const tokenAmount = ethers.utils.parseEther("1");
+
+ let tx = await ethersForeignSigner.sendTransaction({
+ to: proxyColony.address,
+ value: tokenAmount,
+ });
await tx.wait();
- tx = await foreignColony.emitDomainReputationReward(1, accounts[0], "0x1338");
+
+ // Claim on the foreign chain
+ let p = guardianSpy.getPromiseForNextBridgedTransaction();
+ tx = await proxyColony.claimColonyFunds(ADDRESS_ZERO);
await tx.wait();
+ await p;
- const bridgedReputationUpdateCount = await foreignColonyNetwork.getBridgedReputationUpdateCount(foreignChainId, foreignColony.address);
+ // Make a payment that pays out 0.3
- tx = await foreignBridge.setBridgeEnabled(true);
+ const paymentAmount = ethers.utils.parseEther("0.3");
+ tx = await colony.makeExpenditure(1, UINT256_MAX_ETHERS, 1);
await tx.wait();
+ const expenditureId = await colony.getExpenditureCount();
- await forwardTime(MINING_CYCLE_DURATION * 10, undefined, web3HomeProvider);
- await forwardTime(MINING_CYCLE_DURATION * 10, undefined, web3ForeignProvider);
-
- const p = guardianSpy.getPromiseForNextBridgedTransaction();
+ tx = await colony.setExpenditureRecipient(expenditureId, 1, accounts[0]);
+ await tx.wait();
- tx = await foreignColonyNetwork.bridgePendingReputationUpdate(foreignColony.address, bridgedReputationUpdateCount);
+ tx = await colony["setExpenditurePayout(uint256,uint256,uint256,uint256,uint256,address,uint256)"](
+ 1,
+ UINT256_MAX_ETHERS,
+ expenditureId,
+ 1,
+ foreignChainId,
+ ADDRESS_ZERO,
+ paymentAmount,
+ );
await tx.wait();
- await p;
+ const domain1 = await colony.getDomain(1);
+ const expenditure = await colony.getExpenditure(expenditureId);
- // See that it's bridged to the inactive log
- const logAddress = await homeColonyNetwork.getReputationMiningCycle(false);
- const reputationMiningCycleInactive = await new ethers.Contract(logAddress, IReputationMiningCycle.abi, ethersHomeSigner);
+ tx = await colony["moveFundsBetweenPots(uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,address)"](
+ 1,
+ UINT256_MAX_ETHERS,
+ 1,
+ UINT256_MAX_ETHERS,
+ UINT256_MAX_ETHERS,
+ domain1.fundingPotId,
+ expenditure.fundingPotId,
+ paymentAmount,
+ foreignChainId,
+ ADDRESS_ZERO,
+ );
+ await tx.wait();
+ tx = await colony.finalizeExpenditure(expenditureId);
+ await tx.wait();
- const len = await reputationMiningCycleInactive.getReputationUpdateLogLength();
+ const receipientBalanceBefore = await ethersForeignProvider.getBalance(accounts[0]);
- const entry = await reputationMiningCycleInactive.getReputationUpdateLogEntry(len.sub(1));
+ p = guardianSpy.getPromiseForNextBridgedTransaction();
+ tx = await colony["claimExpenditurePayout(uint256,uint256,uint256,address)"](expenditureId, 1, foreignChainId, ADDRESS_ZERO);
+ await tx.wait();
+ await p;
+ // Check bookkeeping on the home chain
- expect(entry.amount.toHexString()).to.equal("0x1327"); // Decayed
- expect(entry.user).to.equal(accounts[0]);
- expect(entry.colony).to.equal(foreignColony.address);
+ const balance1 = await colony["getFundingPotBalance(uint256,uint256,address)"](1, foreignChainId, ADDRESS_ZERO);
+ expect(balance1.toHexString()).to.equal(ethers.utils.parseEther("0.7").toHexString());
- const domain = await foreignColony.getDomain(1);
+ // Check actually paid on foreign chain
+ const colonyBalance = await ethersForeignProvider.getBalance(proxyColony.address);
+ const recipientBalanceAfter = await ethersForeignProvider.getBalance(accounts[0]);
- expect(entry.skillId.toHexString()).to.equal(domain.skillId.toHexString());
+ expect(colonyBalance.toHexString()).to.equal(ethers.utils.parseEther("0.7").toHexString());
+ expect(recipientBalanceAfter.sub(receipientBalanceBefore).toHexString()).to.equal(
+ ethers.utils.parseEther("0.3").sub(ethers.utils.parseEther("0.003").add(1)).toHexString(),
+ );
});
- it("stored reputation emissions have to be emitted in order, but only per-colony", async () => {
- let p = guardianSpy.getPromiseForNextBridgedTransaction(2);
- const foreignColony2 = await setupColony(foreignColonyNetwork);
- await p;
+ it("a bookkeeping error will mean that tokens can no longer be claimed until tokens are returned", async () => {
+ const tokenAmount = ethers.utils.parseEther("100");
- let tx = await foreignBridge.setBridgeEnabled(false);
- await tx.wait();
- tx = await foreignColony.emitDomainReputationReward(1, accounts[0], "0x1338");
- await tx.wait();
- tx = await foreignColony.emitDomainReputationReward(1, accounts[0], "0x1339");
- await tx.wait();
- tx = await foreignColony2.emitDomainReputationReward(1, accounts[0], "0x1340");
+ let tx = await foreignToken["mint(address,uint256)"](proxyColony.address, tokenAmount);
await tx.wait();
- tx = await foreignBridge.setBridgeEnabled(true);
+ // Claim on the foreign chain
+ const p = guardianSpy.getPromiseForNextBridgedTransaction();
+ tx = await proxyColony.claimColonyFunds(foreignToken.address);
await tx.wait();
- const bridgedReputationUpdateCountColony1 = await foreignColonyNetwork.getBridgedReputationUpdateCount(foreignChainId, foreignColony.address);
+ await p;
- const logAddress = await homeColonyNetwork.getReputationMiningCycle(false);
- const reputationMiningCycleInactive = await new ethers.Contract(logAddress, IReputationMiningCycle.abi, ethersHomeSigner);
- const logLengthBefore = await reputationMiningCycleInactive.getReputationUpdateLogLength();
+ // Now remove the tokens
+ const balanceSlot = ethers.utils.keccak256(
+ ethers.utils.concat([ethers.utils.hexZeroPad(proxyColony.address, 32), ethers.utils.hexZeroPad(1, 32)]),
+ );
- // We cannot emit the second bridged
- tx = await foreignColonyNetwork.bridgePendingReputationUpdate(foreignColony.address, bridgedReputationUpdateCountColony1, {
- gasLimit: 1000000,
- });
- await checkErrorRevertEthers(tx.wait(), "colony-network-not-next-pending-update");
+ await ethersForeignProvider.send("hardhat_setStorageAt", [
+ foreignToken.address,
+ balanceSlot,
+ ethers.utils.hexZeroPad(ethers.utils.parseEther("30").toHexString(), 32),
+ ]);
- p = guardianSpy.getPromiseForNextBridgedTransaction();
- // We can emit the third (which was another colony)
- const bridgedReputationUpdateCountColony2 = await foreignColonyNetwork.getBridgedReputationUpdateCount(foreignChainId, foreignColony2.address);
- tx = await foreignColonyNetwork.bridgePendingReputationUpdate(foreignColony2.address, bridgedReputationUpdateCountColony2);
+ tx = await proxyColony.claimColonyFunds(foreignToken.address, { gasLimit: 1000000 });
+ await checkErrorRevertEthers(tx.wait(), "colony-shell-token-bookkeeping-error");
+
+ // Now return the tokens
+ await ethersForeignProvider.send("hardhat_setStorageAt", [
+ foreignToken.address,
+ balanceSlot,
+ ethers.utils.hexZeroPad(ethers.utils.parseEther("100").toHexString(), 32),
+ ]);
+
+ // Mint some more tokens
+ tx = await foreignToken["mint(address,uint256)"](proxyColony.address, ethers.utils.parseEther("100"));
await tx.wait();
- await p;
- p = guardianSpy.getPromiseForNextBridgedTransaction();
- // We can emit the first
- tx = await foreignColonyNetwork.bridgePendingReputationUpdate(foreignColony.address, bridgedReputationUpdateCountColony1.sub(1));
+ // Can now claim
+ const p2 = guardianSpy.getPromiseForNextBridgedTransaction();
+ tx = await proxyColony.claimColonyFunds(foreignToken.address);
await tx.wait();
- await p;
+ await p2;
+ });
- p = guardianSpy.getPromiseForNextBridgedTransaction();
- // And now we can emit the second
- tx = await foreignColonyNetwork.bridgePendingReputationUpdate(foreignColony.address, bridgedReputationUpdateCountColony1);
+ it("can exchange tokens in a domain on one chain for tokens in a domain on another chain via LiFi", async () => {
+ const homeTokenFactory = new ethers.ContractFactory(MetaTxToken.abi, MetaTxToken.bytecode, ethersHomeSigner);
+ const homeToken = await homeTokenFactory.deploy("Test Token", "TT", 18);
+
+ expect(homeToken.address).to.not.equal(foreignToken.address);
+ await (await homeToken.unlock()).wait();
+ await (await foreignToken.unlock()).wait();
+
+ await homeToken["mint(address,uint256)"](homeColony.address, ethers.utils.parseEther("100"));
+ await homeColony["claimColonyFunds(address)"](homeToken.address);
+ await homeColony["addDomain(uint256,uint256,uint256)"](1, UINT256_MAX_ETHERS, 1);
+ const domain1 = await homeColony.getDomain(1);
+ const domain2 = await homeColony.getDomain(2);
+
+ let tx = await homeColony["moveFundsBetweenPots(uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,address)"](
+ 1,
+ UINT256_MAX_ETHERS,
+ 1,
+ UINT256_MAX_ETHERS,
+ 0,
+ domain1.fundingPotId,
+ domain2.fundingPotId,
+ ethers.utils.parseEther("50"),
+ homeChainId,
+ homeToken.address,
+ );
await tx.wait();
- await p;
- const logLengthAfter = await reputationMiningCycleInactive.getReputationUpdateLogLength();
- expect(logLengthAfter.sub(logLengthBefore).toNumber()).to.equal(3);
- });
+ const domain2ReceiverAddress = await homeColonyNetwork.getDomainTokenReceiverAddress(proxyColony.address, 2);
- it("if a bridged reputation emission isn't the next one, it's stored on the mining chain to be added to the log later", async () => {
- const logAddress = await homeColonyNetwork.getReputationMiningCycle(false);
- const reputationMiningCycleInactive = await new ethers.Contract(logAddress, IReputationMiningCycle.abi, ethersHomeSigner);
- const logLengthBefore = await reputationMiningCycleInactive.getReputationUpdateLogLength();
+ const lifi = new ethers.Contract(LIFI_ADDRESS, LiFiFacetProxyMock.abi, ethersHomeSigner);
- let p = guardianSpy.getPromiseForNextBridgedTransaction(2);
- const foreignColony2 = await setupColony(foreignColonyNetwork);
- await p;
+ const txdata = lifi.interface.encodeFunctionData("swapTokensMock(uint256,address,uint256,address,address,uint256)", [
+ homeChainId,
+ homeToken.address,
+ foreignChainId,
+ foreignToken.address,
+ domain2ReceiverAddress,
+ ethers.utils.parseEther("50"),
+ ]);
- guardianSpy.skipCount = 1;
+ tx = await homeColony.exchangeTokensViaLiFi(1, 0, 2, txdata, 0, homeChainId, homeToken.address, ethers.utils.parseEther("50"));
- // Bridge skills
+ const receipt = await tx.wait();
+ const swapEvent = receipt.events
+ .filter((e) => e.address === LIFI_ADDRESS)
+ .map((e) => lifi.interface.parseLog(e))
+ .filter((e) => e.name === "SwapTokens")[0];
+ expect(swapEvent).to.not.be.undefined;
- // This one is skipped
- let tx = await foreignColony.emitDomainReputationReward(1, accounts[0], "0x1338");
- await tx.wait();
- await guardianSpy.waitUntilSkipped();
+ // Okay, so we saw the SwapTokens event. Let's do vaguely what it said for the test,
+ // but in practise this would be the responsibility of whatever entity we've paid to do it
+ // through LiFi.
+ await foreignToken["mint(address,uint256)"](swapEvent.args._toAddress, swapEvent.args._amount); // Implicit 1:1 exchange rate
- // These are bridged and added to the pending log
- p = guardianSpy.getPromiseForNextBridgedTransaction();
- tx = await foreignColony.emitDomainReputationReward(1, accounts[0], "0x1339");
+ // Now claim the tokens on the foreign chain
+ const p = guardianSpy.getPromiseForNextBridgedTransaction();
+ tx = await proxyColony.claimDomainFunds(foreignToken.address, 2, { gasLimit: 1000000 });
await tx.wait();
await p;
- p = guardianSpy.getPromiseForNextBridgedTransaction();
- tx = await foreignColony.emitDomainReputationReward(1, accounts[0], "0x1340");
+ // See if bookkeeping was tracked correctly
+ const domain = await colony.getDomain(2);
+ const balance = await colony["getFundingPotBalance(uint256,uint256,address)"](domain.fundingPotId, foreignChainId, foreignToken.address);
+ expect(balance.toHexString()).to.equal(ethers.utils.parseEther("50").toHexString());
+ });
+
+ it("can exchange tokens in a domain held by the proxy to different tokens also on the proxy", async () => {
+ const foreignTokenFactory = new ethers.ContractFactory(MetaTxToken.abi, MetaTxToken.bytecode, ethersForeignSigner);
+ const foreignToken2 = await foreignTokenFactory.deploy("TT2", "TT2", 18);
+ await (await foreignToken2.unlock()).wait();
+ await (await foreignToken.unlock()).wait();
+
+ let tx = await foreignToken["mint(address,uint256)"](proxyColony.address, ethers.utils.parseEther("100"));
await tx.wait();
- await p;
+ let p = guardianSpy.getPromiseForNextBridgedTransaction();
- // This gets added to the log after being bridged, as it is another colony
- p = guardianSpy.getPromiseForNextBridgedTransaction();
- tx = await foreignColony2.emitDomainReputationReward(1, accounts[0], "0x1341");
+ tx = await proxyColony.claimColonyFunds(foreignToken.address);
await tx.wait();
await p;
- // The log entry for foreignColony2 has been added to the reputation mining cycle contract
- const logLengthAfterBridging = await reputationMiningCycleInactive.getReputationUpdateLogLength();
- expect(logLengthAfterBridging.sub(logLengthBefore).toNumber()).to.equal(1);
-
- // The two log entries have been added to the pending log
- let count = await homeColonyNetwork.getBridgedReputationUpdateCount(foreignChainId, foreignColony.address);
- let pending1 = await homeColonyNetwork.getPendingReputationUpdate(foreignChainId, foreignColony.address, count.add(2));
- expect(pending1.amount.toHexString()).to.equal("0x1339");
- expect(pending1.user).to.equal(accounts[0]);
- expect(pending1.colony).to.equal(foreignColony.address);
+ // Check bookkeeping on the home chain
+ const balance = await colony["getFundingPotBalance(uint256,uint256,address)"](1, foreignChainId, foreignToken.address);
+ expect(balance.toHexString()).to.equal(ethers.utils.parseEther("100").toHexString());
- let pending2 = await homeColonyNetwork.getPendingReputationUpdate(foreignChainId, foreignColony.address, count.add(3));
- expect(pending2.amount.toHexString()).to.equal("0x1340");
- expect(pending2.user).to.equal(accounts[0]);
- expect(pending2.colony).to.equal(foreignColony.address);
-
- // We can't emit those yet because we still haven't bridged the one that was skipped
- tx = await homeColonyNetwork.addPendingReputationUpdate(foreignChainId, foreignColony.address, { gasLimit: 1000000 });
- await checkErrorRevertEthers(tx.wait(), "colony-network-next-update-does-not-exist");
+ // Move tokens from domain 1 to domain 2
+ tx = await colony["addDomain(uint256,uint256,uint256)"](1, UINT256_MAX_ETHERS, 1);
+ await tx.wait();
- // If we bridge over the original one that was skipped, then we can emit the two pending ones
- p = guardianSpy.getPromiseForNextBridgedTransaction();
- await guardianSpy.bridgeSkipped();
- await p;
- count = await homeColonyNetwork.getBridgedReputationUpdateCount(foreignChainId, foreignColony.address);
+ const domain1 = await colony.getDomain(1);
+ const domain2 = await colony.getDomain(2);
- tx = await homeColonyNetwork.addPendingReputationUpdate(foreignChainId, foreignColony.address);
- await tx.wait();
- tx = await homeColonyNetwork.addPendingReputationUpdate(foreignChainId, foreignColony.address);
+ tx = await colony["moveFundsBetweenPots(uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,address)"](
+ 1,
+ UINT256_MAX_ETHERS,
+ 1,
+ UINT256_MAX_ETHERS,
+ 0,
+ domain1.fundingPotId,
+ domain2.fundingPotId,
+ ethers.utils.parseEther("70"),
+ foreignChainId,
+ foreignToken.address,
+ );
await tx.wait();
- // And now they're on the pending log
- const logLengthAfterAdditionalBridging = await reputationMiningCycleInactive.getReputationUpdateLogLength();
- expect(logLengthAfterAdditionalBridging.sub(logLengthAfterBridging).toNumber()).to.equal(3);
-
- // And removed from the colony network
+ // Exchange tokens
+ const domain2ReceiverAddress = await homeColonyNetwork.getDomainTokenReceiverAddress(colony.address, 2);
- pending1 = await homeColonyNetwork.getPendingReputationUpdate(foreignChainId, foreignColony.address, count.add(2));
- expect(pending1.amount.toHexString()).to.equal("0x00");
- expect(pending1.user).to.equal(ADDRESS_ZERO);
- expect(pending1.colony).to.equal(ADDRESS_ZERO);
+ const lifi = new ethers.Contract(LIFI_ADDRESS, LiFiFacetProxyMock.abi, ethersForeignSigner); // Signer doesn't really matter,
+ // we're just calling encodeFunctionData
- pending2 = await homeColonyNetwork.getPendingReputationUpdate(foreignChainId, foreignColony.address, count.add(3));
- expect(pending2.amount.toHexString()).to.equal("0x00");
- expect(pending2.user).to.equal(ADDRESS_ZERO);
- expect(pending2.colony).to.equal(ADDRESS_ZERO);
- });
+ const txdata = lifi.interface.encodeFunctionData("swapTokensMock(uint256,address,uint256,address,address,uint256)", [
+ foreignChainId,
+ foreignToken.address,
+ foreignChainId,
+ foreignToken2.address,
+ domain2ReceiverAddress,
+ ethers.utils.parseEther("70"),
+ ]);
- it(`if a bridged reputation emission isn't the next one, it's stored on the mining chain to be added to the log later
- and decayed if required`, async () => {
- let tx = await foreignBridge.setBridgeEnabled(false);
- await tx.wait();
- tx = await foreignColony.emitDomainReputationReward(1, accounts[0], "0x1338");
+ p = guardianSpy.getPromiseForNextBridgedTransaction();
+ tx = await colony.exchangeTokensViaLiFi(1, 0, 2, txdata, 0, foreignChainId, foreignToken.address, ethers.utils.parseEther("70"));
await tx.wait();
- const bridgedReputationUpdateCount = await foreignColonyNetwork.getBridgedReputationUpdateCount(foreignChainId, foreignColony.address);
+ const receipt = await p;
+ const swapEvent = receipt.logs
+ .filter((e) => e.address === LIFI_ADDRESS)
+ .map((e) => lifi.interface.parseLog(e))
+ .filter((e) => e.name === "SwapTokens")[0];
+ expect(swapEvent).to.not.be.undefined;
- tx = await foreignBridge.setBridgeEnabled(true);
- await tx.wait();
-
- let p = guardianSpy.getPromiseForNextBridgedTransaction();
- await foreignColony.emitDomainReputationReward(1, accounts[0], "0x1339");
- await p;
+ // Okay, so we saw the SwapTokens event. Let's do vaguely what it said for the test,
+ // but in practise this would be the responsibility of whatever entity we've paid to do it
+ // through LiFi.
+ await foreignToken2["mint(address,uint256)"](swapEvent.args._toAddress, swapEvent.args._amount); // Implicit 1:1 exchange rate
+ // Sweep token in to the proxy
p = guardianSpy.getPromiseForNextBridgedTransaction();
- tx = await foreignColonyNetwork.bridgePendingReputationUpdate(foreignColony.address, bridgedReputationUpdateCount);
+ tx = await proxyColony.claimDomainFunds(foreignToken2.address, 2, { gasLimit: 1000000 });
await tx.wait();
- await p;
- const pending1 = await homeColonyNetwork.getPendingReputationUpdate(foreignChainId, foreignColony.address, bridgedReputationUpdateCount.add(1));
- expect(pending1.amount.toHexString()).to.equal("0x1339");
- expect(pending1.user).to.equal(accounts[0]);
- expect(pending1.colony).to.equal(foreignColony.address);
+ // Wait for the sweep to be bridged
+ await p;
- await forwardTime(MINING_CYCLE_DURATION * 10, undefined, web3HomeProvider);
- await forwardTime(MINING_CYCLE_DURATION * 10, undefined, web3ForeignProvider);
- tx = await homeColonyNetwork.addPendingReputationUpdate(foreignChainId, foreignColony.address);
- await tx;
+ // Check bookkeeping on the home chain
+ const balance1 = await colony["getFundingPotBalance(uint256,uint256,address)"](1, foreignChainId, foreignToken.address);
+ const balance2 = await colony["getFundingPotBalance(uint256,uint256,address)"](2, foreignChainId, foreignToken2.address);
+ expect(balance1.toHexString()).to.equal(ethers.utils.parseEther("30").toHexString());
+ expect(balance2.toHexString()).to.equal(ethers.utils.parseEther("70").toHexString());
+
+ // And check balances of the proxy with the tokens
+ const balance3 = await foreignToken.balanceOf(proxyColony.address);
+ const balance4 = await foreignToken2.balanceOf(proxyColony.address);
+ expect(balance3.toHexString()).to.equal(ethers.utils.parseEther("30").toHexString());
+ expect(balance4.toHexString()).to.equal(ethers.utils.parseEther("70").toHexString());
+ });
+ });
- // See that it's bridged to the pending log, but decayed
+ describe("making arbitrary transactions on another chain", async () => {
+ let colony;
+ let foreignToken;
+ beforeEach(async () => {
+ colony = await setupColony(homeColonyNetwork);
- const logAddress = await homeColonyNetwork.getReputationMiningCycle(false);
- const reputationMiningCycleInactive = await new ethers.Contract(logAddress, IReputationMiningCycle.abi, ethersHomeSigner);
+ const events = await homeColonyNetwork.queryFilter(homeColonyNetwork.filters.ColonyAdded());
+ // Deploy a proxy colony on the foreign network
- const len = await reputationMiningCycleInactive.getReputationUpdateLogLength();
+ const colonyCreationSalt = await homeColonyNetwork.getColonyCreationSalt({ blockTag: events[events.length - 1].blockNumber });
- const entry = await reputationMiningCycleInactive.getReputationUpdateLogEntry(len.sub(1));
+ const p = guardianSpy.getPromiseForNextBridgedTransaction();
- expect(entry.amount.toHexString()).to.equal("0x1328");
- expect(entry.user).to.equal(accounts[0]);
- expect(entry.colony).to.equal(foreignColony.address);
+ const tx = await colony.createProxyColony(foreignChainId, colonyCreationSalt, { gasLimit: 1000000 });
+ await tx.wait();
- const domain = await foreignColony.getDomain(1);
+ await p;
+ proxyColony = new ethers.Contract(colony.address, ProxyColony.abi, ethersForeignSigner);
+ // Deploy a token on the foreign network
- expect(entry.skillId.toHexString()).to.equal(domain.skillId.toHexString());
+ const tokenFactory = new ethers.ContractFactory(MetaTxToken.abi, MetaTxToken.bytecode, ethersForeignSigner);
+ foreignToken = await tokenFactory.deploy("Test Token", "TT", 18);
+ await (await foreignToken.unlock()).wait();
+ await (await foreignToken.setOwner(proxyColony.address)).wait();
});
- it(`if a bridged reputation emission is for a skill that hasn't been bridged,
- it's stored on the mining chain to be added to the log later`, async () => {
- const logAddress = await homeColonyNetwork.getReputationMiningCycle(false);
- const reputationMiningCycleInactive = await new ethers.Contract(logAddress, IReputationMiningCycle.abi, ethersHomeSigner);
+ it("can make arbitrary transactions on the foreign chain", async () => {
+ const balanceBefore = await foreignToken.balanceOf(proxyColony.address);
+ const p = guardianSpy.getPromiseForNextBridgedTransaction();
- guardianSpy.skipCount = 2;
- const foreignColony2 = await setupColony(foreignColonyNetwork);
- await guardianSpy.waitUntilSkipped();
+ const payload = foreignToken.interface.encodeFunctionData("mint(address,uint256)", [proxyColony.address, ethers.utils.parseEther("100")]);
- // Bridge skills
- let p = guardianSpy.getPromiseForNextBridgedTransaction();
- let tx = await foreignColony2.emitDomainReputationReward(1, accounts[0], "0x1338");
+ const tx = await colony.makeProxyArbitraryTransaction(foreignChainId, foreignToken.address, payload);
await tx.wait();
await p;
- // A log entries have been added to the pending log
- const count = await homeColonyNetwork.getBridgedReputationUpdateCount(foreignChainId, foreignColony2.address);
- let pending = await homeColonyNetwork.getPendingReputationUpdate(foreignChainId, foreignColony2.address, count.add(1));
- expect(pending.amount.toHexString()).to.equal("0x1338");
- expect(pending.user).to.equal(accounts[0]);
- expect(pending.colony).to.equal(foreignColony2.address);
+ const balanceAfter = await foreignToken.balanceOf(proxyColony.address);
+ expect(balanceAfter.sub(balanceBefore).toHexString()).to.equal(ethers.utils.parseEther("100").toHexString());
+ });
+
+ it("root permissions are required for makeProxyArbitraryTransaction", async () => {
+ const p = guardianSpy.getPromiseForNextBridgedTransaction();
+ let tx = await colony.makeProxyArbitraryTransaction(foreignChainId, foreignToken.address, "0x00000000");
+ await tx.wait();
+ await p;
- // We can't emit it yet, because the skill still hasn't been bridged
- tx = await homeColonyNetwork.addPendingReputationUpdate(foreignChainId, foreignColony2.address, { gasLimit: 1000000 });
- await checkErrorRevertEthers(tx.wait(), "colony-network-invalid-skill-id");
+ await colony.setUserRoles(1, UINT256_MAX_ETHERS, accounts[0], 1, ethers.utils.hexZeroPad("0x00", 32));
+ tx = await colony.makeProxyArbitraryTransaction(foreignChainId, foreignToken.address, "0x00000000", { gasLimit: 1000000 });
+ await checkErrorRevertEthers(tx.wait(), "ds-auth-unauthorized");
+ });
- const logLength1 = await reputationMiningCycleInactive.getReputationUpdateLogLength();
+ it("arbitrary transactions on the foreign chain must go to contracts", async () => {
+ const p = guardianSpy.getPromiseForNextBridgedTransaction();
- // Bridge over the skill creation
- p = guardianSpy.getPromiseForNextBridgedTransaction();
- await guardianSpy.bridgeSkipped();
- await p;
- p = guardianSpy.getPromiseForNextBridgedTransaction();
- await guardianSpy.bridgeSkipped();
- await p;
+ const payload = foreignToken.interface.encodeFunctionData("mint(address,uint256)", [proxyColony.address, ethers.utils.parseEther("100")]);
- // Now try to emit the pending reputation emission
- tx = await homeColonyNetwork.addPendingReputationUpdate(foreignChainId, foreignColony2.address);
+ const tx = await colony.makeProxyArbitraryTransaction(foreignChainId, accounts[0], payload);
await tx.wait();
+ await p;
- // And now it's on the mining cycle contract
- const logLength2 = await reputationMiningCycleInactive.getReputationUpdateLogLength();
- expect(logLength2.sub(logLength1).toNumber()).to.equal(1);
+ await checkErrorRevertEthers(p, "require-execute-call-target-not-contract");
+ });
- // And removed from the colony network
+ it("can make multiple arbitrary transactions on the foreign chain in one go", async () => {
+ const shellBalanceBefore = await foreignToken.balanceOf(proxyColony.address);
+ const colonyBalanceBefore = await colony["getFundingPotBalance(uint256,uint256,address)"](1, foreignChainId, foreignToken.address);
- pending = await homeColonyNetwork.getPendingReputationUpdate(foreignChainId, foreignColony2.address, count.add(1));
- expect(pending.amount.toHexString()).to.equal("0x00");
- expect(pending.user).to.equal(ADDRESS_ZERO);
- expect(pending.colony).to.equal(ADDRESS_ZERO);
- });
+ const p = guardianSpy.getPromiseForNextBridgedTransaction(2);
- it("addReputationUpdateLogFromBridge cannot be called by a non-bridge address", async () => {
- const tx = await homeColonyNetwork.addReputationUpdateLogFromBridge(ADDRESS_ZERO, ADDRESS_ZERO, 0, 0, 0, { gasLimit: 1000000 });
- await checkErrorRevertEthers(tx.wait(), "colony-network-caller-must-be-colony-bridge");
- });
+ const payload1 = foreignToken.interface.encodeFunctionData("mint(address,uint256)", [proxyColony.address, ethers.utils.parseEther("100")]);
+ const arbitraryCallPayload1 = proxyColony.interface.encodeFunctionData("makeArbitraryTransaction", [foreignToken.address, payload1]);
+ const payload2 = proxyColony.interface.encodeFunctionData("claimColonyFunds(address)", [foreignToken.address]);
- it("bridgePendingReputationUpdate can only be called if the bridge is set", async () => {
- // Set bridge to an address that's not a contract, causing the reputation update we subsequently emit to be stored
- await setForeignBridgeData(accounts[0]);
- let tx = await foreignColony.emitDomainReputationReward(1, accounts[0], "0x1338");
+ const multicallPayload = proxyColony.interface.encodeFunctionData("multicall", [[arbitraryCallPayload1, payload2]]);
- const bridgedReputationUpdateCount = await foreignColonyNetwork.getBridgedReputationUpdateCount(foreignChainId, foreignColony.address);
+ const tx = await colony.makeProxyArbitraryTransaction(foreignChainId, proxyColony.address, multicallPayload);
+ await tx.wait();
+ await p;
- await setForeignBridgeData(ADDRESS_ZERO);
+ const shellBalanceAfter = await foreignToken.balanceOf(proxyColony.address);
+ expect(shellBalanceAfter.sub(shellBalanceBefore).toHexString()).to.equal(ethers.utils.parseEther("100").toHexString());
- tx = await foreignColonyNetwork.bridgePendingReputationUpdate(foreignColony.address, bridgedReputationUpdateCount, { gasLimit: 1000000 });
- await checkErrorRevertEthers(tx.wait(), "colony-network-foreign-bridge-not-set");
- await setForeignBridgeData(foreignColonyBridge.address);
- });
+ // Check that the second transaction was successful
- it("bridgePendingReputationUpdate can only bridge an update that exists", async () => {
- const tx = await foreignColonyNetwork.bridgePendingReputationUpdate(foreignColony.address, 1000, { gasLimit: 1000000 });
- await checkErrorRevertEthers(tx.wait(), "colony-network-update-does-not-exist");
+ const colonyBalanceAfter = await colony["getFundingPotBalance(uint256,uint256,address)"](1, foreignChainId, foreignToken.address);
+ expect(colonyBalanceAfter.sub(colonyBalanceBefore).toHexString()).to.equal(ethers.utils.parseEther("100").toHexString());
});
- it("bridgePendingReputationUpdate can be called again if the bridging transaction fails, or the bridge isn't a contract", async () => {
- // Set bridge to an address that's not a contract, causing the reputation update we subsequently emit to be stored
- await setForeignBridgeData(accounts[0]);
- let tx = await foreignColony.emitDomainReputationReward(1, accounts[0], "0x1338");
+ it("invalid cross-chain arbitrary transactions are rejected", async () => {
+ // Check can't target Network
+ let p = guardianSpy.getPromiseForNextBridgedTransaction();
+ const tx = await colony.makeProxyArbitraryTransaction(foreignChainId, remoteColonyNetwork.address, "0x00000000");
await tx.wait();
- const bridgedReputationUpdateCount = await foreignColonyNetwork.getBridgedReputationUpdateCount(foreignChainId, foreignColony.address);
- // Bridge isn't a contract
- tx = await foreignColonyNetwork.bridgePendingReputationUpdate(foreignColony.address, bridgedReputationUpdateCount, { gasLimit: 1000000 });
- await checkErrorRevertEthers(tx.wait(), "colony-network-bridging-tx-unsuccessful");
- await setForeignBridgeData(foreignColonyBridge.address);
+ await checkErrorRevertEthers(p, "colony-cannot-target-network");
- // Bridge is now right address, but disable it.
- tx = await foreignBridge.setBridgeEnabled(false);
- await tx.wait();
+ // Check can't target the bridge
+ p = guardianSpy.getPromiseForNextBridgedTransaction();
+ const tx2 = await colony.makeProxyArbitraryTransaction(foreignChainId, remoteColonyBridge.address, "0x00000000");
+ await tx2.wait();
- tx = await foreignColonyNetwork.bridgePendingReputationUpdate(foreignColony.address, bridgedReputationUpdateCount, { gasLimit: 1000000 });
- await checkErrorRevertEthers(tx.wait(), "colony-network-bridging-tx-unsuccessful");
+ await checkErrorRevertEthers(p, "colony-cannot-target-bridge");
- tx = await foreignBridge.setBridgeEnabled(true);
- await tx.wait();
+ // Otherwise valid transaction, it just fails
+ p = guardianSpy.getPromiseForNextBridgedTransaction();
+ const tx3 = await colony.makeProxyArbitraryTransaction(foreignChainId, foreignToken.address, "0x00000000");
+ await tx3.wait();
- tx = await foreignColonyNetwork.bridgePendingReputationUpdate(foreignColony.address, bridgedReputationUpdateCount, { gasLimit: 1000000 });
- await tx.wait();
+ await checkErrorRevertEthers(p, "require-execute-call-reverted-with-no-error");
});
});
describe("bridge functions are secure", async () => {
it("only the configured colonyNetwork can call `sendMessage`", async () => {
- const tx = await foreignColonyBridge.sendMessage(1, "0x00000000", { gasLimit: 1000000 });
+ const tx = await remoteColonyBridge.sendMessage(1, ADDRESS_ZERO, "0x00000000", { gasLimit: 1000000 });
await checkErrorRevertEthers(tx.wait(), "wormhole-bridge-only-colony-network");
});
- it("setReputationRootHashFromBridge can only be called by the colonyBridge contract", async () => {
- const [, unknownColonyBridge] = await deployBridge(ethersForeignSigner);
- await unknownColonyBridge.setColonyNetworkAddress(foreignColonyNetwork.address);
- await unknownColonyBridge.setColonyBridgeAddress(homeChainId, homeColonyBridge.address);
+ it("an invalid VM is respected", async () => {
+ await homeBridge.setVerifyVMResult(false, "some-good-reason");
const vaa = await guardianSpy.encodeMockVAA(
homeColonyBridge.address,
0,
0,
- foreignColonyNetwork.interface.encodeFunctionData("setReputationRootHashFromBridge", [ethers.utils.hexZeroPad("0xdeadbeef", 32), 0, 1]),
+ remoteColonyNetwork.interface.encodeFunctionData("setProxyColonyResolverAddress", [ADDRESS_ZERO]),
100,
wormholeHomeChainId,
);
- const tx = await unknownColonyBridge.receiveMessage(vaa, { gasLimit: 1000000 });
- await checkErrorRevertEthers(tx.wait(), "colony-network-caller-must-be-colony-bridge");
- });
-
- it("setReputationRootHashFromBridge reverts if bridged transaction did not originate from colonyBridge", async () => {
- const vaa = await guardianSpy.encodeMockVAA(
- ADDRESS_ZERO,
- 0,
- 0,
- foreignColonyNetwork.interface.encodeFunctionData("setReputationRootHashFromBridge", [ethers.utils.hexZeroPad("0xdeadbeef", 32), 0, 1]),
- 100,
- wormholeForeignChainId,
- );
-
- const tx = await foreignColonyBridge.receiveMessage(vaa, { gasLimit: 1000000 });
-
- await checkErrorRevertEthers(tx.wait(), "colony-bridge-bridged-tx-only-from-colony-bridge");
-
- const hash = await foreignColonyNetwork.getReputationRootHash();
- expect(hash).to.not.equal(ethers.utils.hexZeroPad("0xdeadbeef", 32));
+ const tx = await homeColonyBridge.receiveMessage(vaa, { gasLimit: 1000000 });
+ await checkErrorRevertEthers(tx.wait(), "some-good-reason");
+ await homeBridge.setVerifyVMResult(true, "");
});
+ });
- it("setReputationRootHashFromBridge does not allow transactions to be replayed (if not enforced by bridge)", async () => {
- await homeColony.emitDomainReputationReward(1, accounts[0], "0x1337");
-
- // Advance mining cycle twice
- await forwardTime(MINING_CYCLE_DURATION + CHALLENGE_RESPONSE_WINDOW_DURATION, undefined, web3HomeProvider);
- await client.addLogContentsToReputationTree();
- await client.submitRootHash();
- await client.confirmNewHash();
+ describe("ProxyColony functions are secure", async () => {
+ let colony;
+ beforeEach(async () => {
+ colony = await setupColony(homeColonyNetwork);
- await forwardTime(MINING_CYCLE_DURATION + CHALLENGE_RESPONSE_WINDOW_DURATION, undefined, web3HomeProvider);
- await client.addLogContentsToReputationTree();
- await client.submitRootHash();
- await client.confirmNewHash();
+ const events = await homeColonyNetwork.queryFilter(homeColonyNetwork.filters.ColonyAdded());
+ // Deploy a proxy colony on the foreign network
+ const colonyCreationSalt = await homeColonyNetwork.getColonyCreationSalt({ blockTag: events[events.length - 1].blockNumber });
- const homeRootHash1 = await homeColonyNetwork.getReputationRootHash();
+ const p = guardianSpy.getPromiseForNextBridgedTransaction();
- guardianSpy.skipCount = 1;
- // Bridge root hash
- let tx = await homeColonyNetwork.bridgeCurrentRootHash(foreignChainId);
+ const tx = await colony.createProxyColony(foreignChainId, colonyCreationSalt, { gasLimit: 1000000 });
await tx.wait();
- await guardianSpy.waitUntilSkipped();
- const skippedTx = guardianSpy.skipped[0];
-
- let p = guardianSpy.getPromiseForNextBridgedTransaction();
- await guardianSpy.bridgeSkipped();
await p;
+ proxyColony = new ethers.Contract(colony.address, ProxyColony.abi, ethersForeignSigner);
+ });
- const foreignRootHash1 = await foreignColonyNetwork.getReputationRootHash();
-
- expect(homeRootHash1).to.equal(foreignRootHash1);
+ it("a non-bridge address cannot call transferFromBridge", async () => {
+ const tx = await proxyColony.transferFromBridge(ADDRESS_ZERO, ADDRESS_ZERO, 0, { gasLimit: 1000000 });
+ await checkErrorRevertEthers(tx.wait(), "colony-only-bridge");
+ });
- // Advance mining cycle twice
- await forwardTime(MINING_CYCLE_DURATION + CHALLENGE_RESPONSE_WINDOW_DURATION, undefined, web3HomeProvider);
- await client.addLogContentsToReputationTree();
- await client.submitRootHash();
- await client.confirmNewHash();
+ it("a non-bridge address cannot call makeArbitraryTransaction", async () => {
+ const tx = await proxyColony.makeArbitraryTransaction(ADDRESS_ZERO, "0x00", { gasLimit: 1000000 });
+ await checkErrorRevertEthers(tx.wait(), "colony-only-bridge");
+ });
+ });
- await forwardTime(MINING_CYCLE_DURATION + CHALLENGE_RESPONSE_WINDOW_DURATION, undefined, web3HomeProvider);
- await client.addLogContentsToReputationTree();
- await client.submitRootHash();
- await client.confirmNewHash();
+ describe("ProxyColonyNetwork functions are secure", async () => {
+ let proxyColonyNetwork2;
+ before(async () => {
+ proxyColonyNetwork2 = await new ethers.Contract(NETWORK_ADDRESS, ProxyColonyNetwork.abi, ethersForeignSigner2);
+ });
- const homeRootHash2 = await homeColonyNetwork.getReputationRootHash();
+ it("only authed accounts can call setProxyColonyResolverAddress", async () => {
+ let tx = await proxyColonyNetwork2.setProxyColonyResolverAddress(ADDRESS_ZERO, { gasLimit: 1000000 });
+ await checkErrorRevertEthers(tx.wait(), "ds-auth-unauthorized");
- p = guardianSpy.getPromiseForNextBridgedTransaction();
- tx = await homeColonyNetwork.bridgeCurrentRootHash(foreignChainId);
+ await remoteColonyNetwork.setOwner(accounts[1]);
+ tx = await proxyColonyNetwork2.setProxyColonyResolverAddress(ADDRESS_ZERO, { gasLimit: 1000000 });
await tx.wait();
- await p;
-
- const foreignRootHash2 = await foreignColonyNetwork.getReputationRootHash();
- expect(foreignRootHash2).to.equal(homeRootHash2);
+ });
- // Try and replay
- guardianSpy.skipped = [skippedTx];
+ it("a non-authed account cannot call setHomeChainId", async () => {
+ let tx = await proxyColonyNetwork2.setHomeChainId(1, { gasLimit: 1000000 });
+ await checkErrorRevertEthers(tx.wait(), "ds-auth-unauthorized");
+ await remoteColonyNetwork.setOwner(accounts[1]);
- p = guardianSpy.getPromiseForNextBridgedTransaction();
- await guardianSpy.bridgeSkipped();
- const bridgingTx = await p;
- await checkErrorRevertEthers(bridgingTx.wait(), "colony-mining-bridge-invalid-nonce");
+ tx = await proxyColonyNetwork2.setHomeChainId(1, { gasLimit: 1000000 });
+ await tx.wait();
+ });
- // Had no effect
+ it("a non-bridge address cannot call createProxyColonyFromBridge", async () => {
+ const tx = await remoteColonyNetwork.createProxyColonyFromBridge(HASHZERO, { gasLimit: 1000000 });
+ await checkErrorRevertEthers(tx.wait(), "colony-network-caller-must-be-colony-bridge");
+ });
- const foreignRootHash3 = await foreignColonyNetwork.getReputationRootHash();
+ it("a non-proxy-colony address cannot call bridgeMessage", async () => {
+ const tx = await remoteColonyNetwork.bridgeMessage(HASHZERO, { gasLimit: 1000000 });
+ await checkErrorRevertEthers(tx.wait(), "colony-network-caller-must-be-proxy-colony");
+ });
+ });
- expect(foreignRootHash3).to.equal(foreignRootHash2);
- expect(foreignRootHash3).to.not.equal(foreignRootHash1);
+ describe("ColonyNetwork functions are secure", async () => {
+ it("a non-colony address cannot call bridgeMessage", async () => {
+ const tx = await homeColonyNetwork.bridgeMessage(1, HASHZERO, { gasLimit: 1000000 });
+ await checkErrorRevertEthers(tx.wait(), "colony-caller-must-be-colony");
});
+ });
- it("addSkillFromBridge can only be called by the colonyBridge contract", async () => {
- const skillCountBefore = await homeColonyNetwork.getSkillCount();
+ describe("Invalid interactions with bridging system are handled appropriately", async () => {
+ it("Can't bridge to a chain that's not supported", async () => {
+ const tx = await homeColony.makeProxyArbitraryTransaction(111, ADDRESS_ZERO, "0x00000000", { gasLimit: 1000000 });
+ await checkErrorRevertEthers(tx.wait(), "colony-bridge-not-known-chain");
+ });
- const [, unknownColonyBridge] = await deployBridge(ethersHomeSigner);
- await unknownColonyBridge.setColonyBridgeAddress(foreignChainId, foreignColonyBridge.address);
- await unknownColonyBridge.setColonyNetworkAddress(homeColonyNetwork.address);
+ it("Valid VAAs that aren't from a colony bridge are rejected", async () => {
const vaa = await guardianSpy.encodeMockVAA(
- foreignColonyBridge.address,
+ homeColonyBridge.address,
0,
0,
- homeColonyNetwork.interface.encodeFunctionData("addSkillFromBridge", [1, 2]),
+ remoteColonyNetwork.interface.encodeFunctionData("setProxyColonyResolverAddress", [ADDRESS_ZERO]),
100,
- wormholeForeignChainId,
+ 1,
);
- const tx = await unknownColonyBridge.receiveMessage(vaa, { gasLimit: 1000000 });
- await checkErrorRevertEthers(tx.wait(), "colony-network-caller-must-be-colony-bridge");
-
- const skillCountAfter = await homeColonyNetwork.getSkillCount();
- expect(skillCountAfter.toHexString()).to.be.equal(skillCountBefore.toHexString());
+ const tx = await remoteColonyBridge.receiveMessage(vaa, { gasLimit: 1000000 });
+ await checkErrorRevertEthers(tx.wait(), "colony-bridge-bridged-tx-only-from-colony-bridge");
});
- it("addSkillFromBridge reverts if bridged transaction did not originate from colonyNetwork", async () => {
- const skillCountBefore = await homeColonyNetwork.getSkillCount();
-
+ it("Valid VAAs that aren't for the right chain are rejected", async () => {
const vaa = await guardianSpy.encodeMockVAA(
- ADDRESS_ZERO,
+ homeColonyBridge.address,
0,
0,
- foreignColonyNetwork.interface.encodeFunctionData("setReputationRootHashFromBridge", [ethers.utils.hexZeroPad("0xdeadbeef", 32), 0, 1]),
+ new ethers.utils.AbiCoder().encode(
+ ["uint256", "address", "bytes"],
+ [7777, ADDRESS_ZERO, remoteColonyNetwork.interface.encodeFunctionData("setProxyColonyResolverAddress", [ADDRESS_ZERO])],
+ ),
100,
- wormholeForeignChainId,
+ wormholeHomeChainId,
);
+ const tx = await remoteColonyBridge.receiveMessage(vaa, { gasLimit: 1000000 });
+ // await tx.wait();
+ await checkErrorRevertEthers(tx.wait(), "colony-bridge-destination-chain-id-mismatch");
+ });
+ });
- const tx = await foreignColonyBridge.receiveMessage(vaa, { gasLimit: 1000000 });
+ describe("OneTxPayment", async () => {
+ let version;
+ before(async () => {
+ const oneTxPaymentFactory = new ethers.ContractFactory(OneTxPayment.abi, OneTxPayment.bytecode, ethersHomeSigner);
+ const extension = await oneTxPaymentFactory.deploy();
+ version = await extension.version();
+ });
- await checkErrorRevertEthers(tx.wait(), "colony-bridge-bridged-tx-only-from-colony-bridge");
+ beforeEach(async () => {
+ const events = await homeColonyNetwork.queryFilter(homeColonyNetwork.filters.ColonyAdded());
+ // homeColonyNetwork.fil
+ // Deploy a proxy colony on the foreign network
- const skillCountAfter = await homeColonyNetwork.getSkillCount();
- expect(skillCountAfter.toHexString()).to.be.equal(skillCountBefore.toHexString());
- });
+ const colonyCreationSalt = await homeColonyNetwork.getColonyCreationSalt({ blockTag: events[events.length - 1].blockNumber });
- it("addSkillFromBridge does not allow transactions to be replayed (if not enforced by bridge)", async () => {
- guardianSpy.skipCount = 2;
+ const p = guardianSpy.getPromiseForNextBridgedTransaction();
- // Create a skill on foreign chain
- let tx = await foreignColony["addDomain(uint256,uint256,uint256)"](1, UINT256_MAX_ETHERS, 1);
+ const tx = await homeColony.createProxyColony(foreignChainId, colonyCreationSalt, { gasLimit: 1000000 });
await tx.wait();
- // Create another
- tx = await foreignColony["addDomain(uint256,uint256,uint256)"](1, UINT256_MAX_ETHERS, 1);
+ await p;
+ proxyColony = new ethers.Contract(homeColony.address, ProxyColony.abi, ethersForeignSigner);
+ // Deploy a token on the foreign network
+ });
+
+ it("Can make a OneTxPayment cross-chain, including the fee", async () => {
+ // Set fee on the home chain
+ let tx = await homeMetacolony.setNetworkFeeInverse(100);
await tx.wait();
- await guardianSpy.waitUntilSkipped();
- const skippedTx1 = guardianSpy.skipped[0];
- const skippedTx2 = guardianSpy.skipped[1];
- // Bridge out of order
- guardianSpy.skipped = [skippedTx2];
+ const tokenFactory = new ethers.ContractFactory(MetaTxToken.abi, MetaTxToken.bytecode, ethersForeignSigner);
+ const foreignToken = await tokenFactory.deploy("Test Token", "TT", 18);
+ await (await foreignToken.unlock()).wait();
+
+ const tokenAmount = ethers.utils.parseEther("100");
+ await foreignToken["mint(address,uint256)"](proxyColony.address, tokenAmount);
+
let p = guardianSpy.getPromiseForNextBridgedTransaction();
- await guardianSpy.bridgeSkipped();
- let bridgingTx = await p;
- await bridgingTx.wait();
- // Replay
- guardianSpy.skipped = [skippedTx2];
- p = guardianSpy.getPromiseForNextBridgedTransaction();
- await guardianSpy.bridgeSkipped();
- bridgingTx = await p;
- await checkErrorRevertEthers(bridgingTx.wait(), "colony-network-skill-already-pending");
+ tx = await proxyColony.claimColonyFunds(foreignToken.address);
+ await tx.wait();
- // Bridge first tx
- guardianSpy.skipped = [skippedTx1];
- p = guardianSpy.getPromiseForNextBridgedTransaction();
- await guardianSpy.bridgeSkipped();
- bridgingTx = await p;
- await bridgingTx.wait();
+ await p;
- // Replay first tx
- guardianSpy.skipped = [skippedTx1];
- p = guardianSpy.getPromiseForNextBridgedTransaction();
- await guardianSpy.bridgeSkipped();
- bridgingTx = await p;
- await checkErrorRevertEthers(bridgingTx.wait(), "colony-network-skill-already-added");
- });
+ const paymentAmount = ethers.utils.parseEther("30");
+ const ONE_TX_PAYMENT = ethers.utils.id("OneTxPayment");
+ await homeColony.installExtension(ONE_TX_PAYMENT, version);
- // addReputationUpdateLogFromBridge
- it("addReputationUpdateLogFromBridge can only be called by the colonyBridge contract", async () => {
- const [, unknownColonyBridge] = await deployBridge(ethersHomeSigner);
- await unknownColonyBridge.setColonyNetworkAddress(homeColonyNetwork.address);
- await unknownColonyBridge.setColonyBridgeAddress(foreignChainId, foreignColonyBridge.address);
- const vaa = await guardianSpy.encodeMockVAA(
- foreignColonyBridge.address,
- 0,
- 0,
- homeColonyNetwork.interface.encodeFunctionData("addReputationUpdateLogFromBridge", [ADDRESS_ZERO, ADDRESS_ZERO, 0, 0, 0]),
- 100,
- wormholeForeignChainId,
- );
- const tx = await unknownColonyBridge.receiveMessage(vaa, { gasLimit: 1000000 });
- await checkErrorRevertEthers(tx.wait(), "colony-network-caller-must-be-colony-bridge");
+ const oneTxPaymentAddress = await homeColonyNetwork.getExtensionInstallation(ONE_TX_PAYMENT, homeColony.address);
+ const oneTxPayment = await new ethers.Contract(oneTxPaymentAddress, OneTxPayment.abi, ethersHomeSigner);
- // const tx = await homeColonyNetwork.addReputationUpdateLogFromBridge(ADDRESS_ZERO, ADDRESS_ZERO, 0, 0, 0, { gasLimit: 1000000 });
- // await checkErrorRevertEthers(tx.wait(), "colony-network-not-known-bridge");
- });
+ const ROLES = rolesToBytes32([ARBITRATION_ROLE, FUNDING_ROLE, ADMINISTRATION_ROLE]);
+ await homeColony.setUserRoles(1, UINT256_MAX_ETHERS, oneTxPayment.address, 1, ROLES);
- it("addReputationUpdateLogFromBridge reverts if bridged transaction did not originate from colonyNetwork", async () => {
- const vaa = await guardianSpy.encodeMockVAA(
- ADDRESS_ZERO,
- 0,
+ const balanceBefore = await foreignToken.balanceOf(accounts[0]);
+ const networkBalanceBefore = await foreignToken.balanceOf(remoteColonyNetwork.address);
+
+ p = guardianSpy.getPromiseForNextBridgedTransaction();
+
+ tx = await oneTxPayment["makePayment(uint256,uint256,uint256,uint256,address[],uint256[],address[],uint256[],uint256,uint256)"](
+ 1,
+ UINT256_MAX_ETHERS,
+ 1,
+ UINT256_MAX_ETHERS,
+ [accounts[0]],
+ [foreignChainId],
+ [foreignToken.address],
+ [paymentAmount],
+ 1,
0,
- foreignColonyNetwork.interface.encodeFunctionData("addReputationUpdateLogFromBridge", [ADDRESS_ZERO, ADDRESS_ZERO, 0, 0, 0]),
- 100,
- wormholeForeignChainId,
);
+ await tx.wait();
+ await p;
- const tx = await foreignColonyBridge.receiveMessage(vaa, { gasLimit: 1000000 });
-
- await checkErrorRevertEthers(tx.wait(), "colony-bridge-bridged-tx-only-from-colony-bridge");
- });
+ const balanceAfter = await foreignToken.balanceOf(accounts[0]);
+ expect(balanceAfter.sub(balanceBefore).toHexString()).to.equal(paymentAmount.sub(ethers.utils.parseEther("0.3").add(1)).toHexString());
- it("addReputationUpdateLogFromBridge does not allow transactions to be replayed (if not enforced by bridge)", async () => {
- guardianSpy.skipCount = 2;
+ const networkBalanceAfter = await foreignToken.balanceOf(remoteColonyNetwork.address);
+ expect(networkBalanceAfter.sub(networkBalanceBefore).toHexString()).to.equal(ethers.utils.parseEther("0.3").add(1).toHexString());
- // Emit reputation on foreign chain
- let tx = await foreignColony.emitDomainReputationReward(1, accounts[0], "0x1337");
+ tx = await homeMetacolony.setNetworkFeeInverse(UINT256_MAX_ETHERS);
await tx.wait();
+ });
+ });
- // Emit more reputation
- tx = await foreignColony.emitDomainReputationReward(1, accounts[0], "0x1337");
- await tx.wait();
- await guardianSpy.waitUntilSkipped();
- const skippedTx1 = guardianSpy.skipped[0];
- const skippedTx2 = guardianSpy.skipped[1];
+ describe("Wormholescan API mock should work as expected", async () => {
+ it("the operations endpoint should return the values ", async () => {
+ const colony = await setupColony(homeColonyNetwork);
- // Bridge out of order
- guardianSpy.skipped = [skippedTx2];
- let p = guardianSpy.getPromiseForNextBridgedTransaction();
- await guardianSpy.bridgeSkipped();
- let bridgingTx = await p;
- await bridgingTx.wait();
+ // const homeWormholeAddress = await homeBridge.wormhole();
+ // const foreignWormholeAddress = await remoteColonyNetwork.wormhole();
- // Replay
- guardianSpy.skipped = [skippedTx2];
- p = guardianSpy.getPromiseForNextBridgedTransaction();
- await guardianSpy.bridgeSkipped();
- bridgingTx = await p;
- await checkErrorRevertEthers(bridgingTx.wait(), "colony-network-update-already-pending");
+ const events = await homeColonyNetwork.queryFilter(homeColonyNetwork.filters.ColonyAdded());
+ // Deploy a proxy colony on the foreign network
- // Bridge first tx
- guardianSpy.skipped = [skippedTx1];
- p = guardianSpy.getPromiseForNextBridgedTransaction();
- await guardianSpy.bridgeSkipped();
- bridgingTx = await p;
- await bridgingTx.wait();
+ const colonyCreationSalt = await homeColonyNetwork.getColonyCreationSalt({ blockTag: events[events.length - 1].blockNumber });
- // Replay first tx
- guardianSpy.skipped = [skippedTx1];
- p = guardianSpy.getPromiseForNextBridgedTransaction();
- await guardianSpy.bridgeSkipped();
- bridgingTx = await p;
- await checkErrorRevertEthers(bridgingTx.wait(), "colony-network-update-already-added");
- });
+ const p = guardianSpy.getPromiseForNextBridgedTransaction();
- it("an invalid VM is respected", async () => {
- await homeBridge.setVerifyVMResult(false, "some-good-reason");
- const vaa = await guardianSpy.encodeMockVAA(
+ const tx = await colony.createProxyColony(foreignChainId, colonyCreationSalt, { gasLimit: 1000000 });
+ const requestReceipt = await tx.wait();
+
+ const homeWormhole = new ethers.Contract(homeBridge, IWormhole.abi, ethersHomeSigner);
+ const wormholeEvent = homeWormhole.interface.parseLog(requestReceipt.logs.filter((l) => l.address === homeBridge.address)[0]);
+ const senderWormholeAddress = ethers.utils.hexZeroPad(wormholeEvent.args.sender, 32);
+ const executionReceipt = await p;
+ let apiResponse;
+
+ try {
+ apiResponse = await fetch(
+ `http://localhost:3001/api/v1/operations/${wormholeHomeChainId}/${senderWormholeAddress}/${wormholeEvent.args.sequence.toString()}`,
+ );
+ } catch (err) {
+ console.log(err);
+ }
+ const res = await apiResponse.json();
+
+ expect(res.sourceChain.transaction.txHash).to.equal(requestReceipt.transactionHash);
+ expect(res.targetChain.transaction.txHash).to.equal(executionReceipt.transactionHash);
+ const expectedVaa = await guardianSpy.encodeMockVAA(
homeColonyBridge.address,
+ wormholeEvent.args.sequence,
0,
+ wormholeEvent.args.payload,
0,
- foreignColonyNetwork.interface.encodeFunctionData("setReputationRootHashFromBridge", [ethers.utils.hexZeroPad("0xdeadbeef", 32), 0, 1]),
- 100,
wormholeHomeChainId,
);
- const tx = await homeColonyBridge.receiveMessage(vaa, { gasLimit: 1000000 });
- await checkErrorRevertEthers(tx.wait(), "some-good-reason");
- await homeBridge.setVerifyVMResult(true, "");
+ // Check VAA
+ expect(res.vaa.raw).to.equal(expectedVaa);
});
});
});
diff --git a/test/deploy-proxy-network-fixture.js b/test/deploy-proxy-network-fixture.js
new file mode 100644
index 0000000000..f2ef0364a0
--- /dev/null
+++ b/test/deploy-proxy-network-fixture.js
@@ -0,0 +1,82 @@
+/* globals artifacts, hre */
+
+const EtherRouter = artifacts.require("EtherRouter");
+const EtherRouterCreate3 = artifacts.require("EtherRouterCreate3");
+const Resolver = artifacts.require("Resolver");
+const DomainTokenReceiver = artifacts.require("DomainTokenReceiver");
+
+const truffleContract = require("@truffle/contract");
+const { setCode } = require("@nomicfoundation/hardhat-network-helpers");
+const createXABI = require("../lib/createx/artifacts/src/ICreateX.sol/ICreateX.json");
+
+const { setupEtherRouter } = require("../helpers/upgradable-contracts");
+const { CREATEX_ADDRESS } = require("../helpers/constants");
+
+const { setupProxyColonyNetwork } = require("../helpers/upgradable-contracts");
+
+const ProxyColonyNetwork = artifacts.require("ProxyColonyNetwork");
+const ProxyColony = artifacts.require("ProxyColony");
+const LiFiFacetProxyMock = artifacts.require("LiFiFacetProxyMock");
+
+module.exports = async () => {
+ const accounts = await web3.eth.getAccounts();
+
+ await hre.run("ensure-createx-deployed");
+ const CreateX = truffleContract({ abi: createXABI.abi });
+ CreateX.setProvider(web3.currentProvider);
+ const createX = await CreateX.at(CREATEX_ADDRESS);
+
+ // This is a fake instance of an etherRouter, just so we can call encodeABs
+ const fakeEtherRouter = await EtherRouterCreate3.at(CREATEX_ADDRESS);
+ const setOwnerData = fakeEtherRouter.contract.methods.setOwner(accounts[0]).encodeABI();
+
+ const tx = await createX.methods["deployCreate3AndInit(bytes32,bytes,bytes,(uint256,uint256))"](
+ `0xb77d57f4959eafa0339424b83fcfaf9c15407461005e95d52076387600e2c1e9`,
+ EtherRouterCreate3.bytecode,
+ setOwnerData,
+ [0, 0],
+ { from: accounts[0] },
+ );
+
+ const etherRouter = await EtherRouter.at(tx.logs.filter((log) => log.event === "ContractCreation")[0].args.newContract);
+
+ const proxyColonyNetworkImplementation = await ProxyColonyNetwork.new();
+ ProxyColonyNetwork.setAsDeployed(proxyColonyNetworkImplementation);
+
+ let resolver = await Resolver.new();
+
+ await Resolver.setAsDeployed(resolver);
+
+ await setupProxyColonyNetwork(etherRouter, proxyColonyNetworkImplementation, resolver);
+
+ // Set up the resolver for shell colonies and register it with the network
+
+ resolver = await Resolver.new();
+ const proxyColonyImplementation = await ProxyColony.new();
+
+ await setupEtherRouter("bridging", "ProxyColony", { ProxyColony: proxyColonyImplementation.address }, resolver);
+ const proxyColonyNetwork = await ProxyColonyNetwork.at(etherRouter.address);
+
+ await proxyColonyNetwork.setProxyColonyResolverAddress(resolver.address);
+
+ // Set up the resolver for DomainTokenReceiver
+
+ resolver = await Resolver.new();
+ const domainTokenReceiverImplementation = await DomainTokenReceiver.new();
+ await setupEtherRouter("common", "DomainTokenReceiver", { DomainTokenReceiver: domainTokenReceiverImplementation.address }, resolver);
+ await proxyColonyNetwork.setDomainTokenReceiverResolver(resolver.address);
+
+ // Deploy LiFiMock to LiFi address
+ try {
+ await setCode("0x1231DEB6f5749EF6cE6943a275A1D3E7486F4EaE", LiFiFacetProxyMock.deployedBytecode);
+ } catch (error) {
+ if (error.message.includes("OnlyHardhatNetworkError")) {
+ await new Promise(function (resolve) {
+ web3.provider.send(
+ { method: "evm_setCode", params: ["0x1231DEB6f5749EF6cE6943a275A1D3E7486F4EaE", LiFiFacetProxyMock.deployedBytecode] },
+ resolve,
+ );
+ });
+ }
+ }
+};
diff --git a/test/extensions/one-tx-payment.js b/test/extensions/one-tx-payment.js
index 45b5a1a25e..8ffcc4d545 100644
--- a/test/extensions/one-tx-payment.js
+++ b/test/extensions/one-tx-payment.js
@@ -216,7 +216,18 @@ contract("One transaction payments", (accounts) => {
await fundColonyWithTokens(colony, token, INITIAL_FUNDING);
await checkErrorRevert(
- oneTxPayment.makePayment(2, UINT256_MAX, 2, UINT256_MAX, [USER1], [token.address], [10], 2, localSkillId, { from: USER1 }),
+ oneTxPayment.methods["makePayment(uint256,uint256,uint256,uint256,address[],address[],uint256[],uint256,uint256)"](
+ 2,
+ UINT256_MAX,
+ 2,
+ UINT256_MAX,
+ [USER1],
+ [token.address],
+ [10],
+ 2,
+ localSkillId,
+ { from: USER1 },
+ ),
"one-tx-payment-not-authorized",
);
});
@@ -229,7 +240,18 @@ contract("One transaction payments", (accounts) => {
await colony.setArbitrationRole(1, 0, USER1, 2, true);
await fundColonyWithTokens(colony, token, INITIAL_FUNDING);
- await oneTxPayment.makePayment(1, 0, 2, UINT256_MAX, [USER1], [token.address], [10], 2, localSkillId, { from: USER1 });
+ await oneTxPayment.methods["makePayment(uint256,uint256,uint256,uint256,address[],address[],uint256[],uint256,uint256)"](
+ 1,
+ 0,
+ 2,
+ UINT256_MAX,
+ [USER1],
+ [token.address],
+ [10],
+ 2,
+ localSkillId,
+ { from: USER1 },
+ );
});
it("should allow a single-transaction to occur when user has different permissions than contract", async () => {
diff --git a/test/extensions/staked-expenditure.js b/test/extensions/staked-expenditure.js
index 05ca3a257f..e3fe08ca37 100644
--- a/test/extensions/staked-expenditure.js
+++ b/test/extensions/staked-expenditure.js
@@ -330,6 +330,26 @@ contract("StakedExpenditure", (accounts) => {
);
});
+ it("cannot slash the stake if the expenditure is already cancelled", async () => {
+ await stakedExpenditure.makeExpenditureWithStake(1, UINT256_MAX, 1, domain1Key, domain1Value, domain1Mask, domain1Siblings, { from: USER0 });
+ const expenditureId = await colony.getExpenditureCount();
+ await colony.cancelExpenditure(expenditureId);
+
+ await checkErrorRevert(
+ stakedExpenditure.cancelAndPunish(1, UINT256_MAX, 1, UINT256_MAX, expenditureId, true, { from: USER1 }),
+ "staked-expenditure-expenditure-already-cancelled",
+ );
+ });
+
+ it("cannot slash the stake if the expenditure is still in draft", async () => {
+ await stakedExpenditure.makeExpenditureWithStake(1, UINT256_MAX, 1, domain1Key, domain1Value, domain1Mask, domain1Siblings, { from: USER0 });
+ const expenditureId = await colony.getExpenditureCount();
+
+ await checkErrorRevert(
+ stakedExpenditure.cancelAndPunish(1, UINT256_MAX, 1, UINT256_MAX, expenditureId, true, { from: USER1 }),
+ "staked-expenditure-expenditure-still-draft",
+ );
+ });
it("can cancel the expenditure without penalty", async () => {
await stakedExpenditure.makeExpenditureWithStake(1, UINT256_MAX, 1, domain1Key, domain1Value, domain1Mask, domain1Siblings, { from: USER0 });
const expenditureId = await colony.getExpenditureCount();
diff --git a/test/extensions/whitelist.js b/test/extensions/whitelist.js
index f85ee604ab..c02cb5ba90 100644
--- a/test/extensions/whitelist.js
+++ b/test/extensions/whitelist.js
@@ -258,5 +258,19 @@ contract("Whitelist", (accounts) => {
status = await whitelist.isApproved(USER1);
expect(status).to.be.false;
});
+
+ it("cannot approve users if deprecated", async () => {
+ await whitelist.initialise(true, "");
+ await colony.deprecateExtension(WHITELIST, true, { from: USER0 });
+
+ await checkErrorRevert(whitelist.approveUsers([USER1], true, { from: USER0 }), "colony-extension-deprecated");
+ });
+
+ it("users can't sign an agreement if deprecated", async () => {
+ await whitelist.initialise(true, "");
+ await colony.deprecateExtension(WHITELIST, true, { from: USER0 });
+
+ await checkErrorRevert(whitelist.signAgreement(IPFS_HASH, { from: USER0 }), "colony-extension-deprecated");
+ });
});
});
diff --git a/test/misc/chainid.js b/test/misc/chainid.js
index 50d42954fe..8dabf35c34 100644
--- a/test/misc/chainid.js
+++ b/test/misc/chainid.js
@@ -24,12 +24,11 @@ const {
isXdai,
getChainId,
} = require("../../helpers/test-helper");
-const { MINING_CYCLE_DURATION, MIN_STAKE, CHALLENGE_RESPONSE_WINDOW_DURATION, WAD, DEFAULT_STAKE, XDAI_CHAINID } = require("../../helpers/constants");
+const { MINING_CYCLE_DURATION, MIN_STAKE, CHALLENGE_RESPONSE_WINDOW_DURATION, WAD, DEFAULT_STAKE } = require("../../helpers/constants");
const { expect } = chai;
const ENSRegistry = artifacts.require("ENSRegistry");
const DutchAuction = artifacts.require("DutchAuction");
-const ITokenLocking = artifacts.require("ITokenLocking");
const Token = artifacts.require("Token");
chai.use(bnChai(web3.utils.BN));
@@ -54,18 +53,14 @@ contract("Contract Storage", (accounts) => {
({ metaColony, clnyToken } = await setupMetaColonyWithLockedCLNYToken(colonyNetwork));
const ensRegistry = await ENSRegistry.new();
await setupENSRegistrar(colonyNetwork, ensRegistry, accounts[0]);
- if (await isXdai()) {
- await giveUserCLNYTokensAndStake(colonyNetwork, MINER1, DEFAULT_STAKE);
- await giveUserCLNYTokensAndStake(colonyNetwork, MINER2, DEFAULT_STAKE);
- await giveUserCLNYTokensAndStake(colonyNetwork, MINER3, DEFAULT_STAKE);
-
- await metaColony.initialiseReputationMining(chainId, ethers.constants.HashZero, 0);
- } else {
- await metaColony.initialiseReputationMining(XDAI_CHAINID, ethers.constants.HashZero, 0);
- }
+ await giveUserCLNYTokensAndStake(colonyNetwork, MINER1, DEFAULT_STAKE);
+ await giveUserCLNYTokensAndStake(colonyNetwork, MINER2, DEFAULT_STAKE);
+ await giveUserCLNYTokensAndStake(colonyNetwork, MINER3, DEFAULT_STAKE);
+
+ await metaColony.initialiseReputationMining(chainId, ethers.constants.HashZero, 0);
});
- describe("Should behave differently based on the network deployed to", () => {
+ describe("Should behave appropriately with old per-chain behaviours", () => {
it("should be able to get the domain name", async () => {
await metaColony.registerColonyLabel("meta", "", { from: accounts[0] });
if (await isMainnet()) {
@@ -79,26 +74,7 @@ contract("Contract Storage", (accounts) => {
}
});
- it("can only stake tokens for mining (and therefore can only mine) on the mining chain", async () => {
- await giveUserCLNYTokens(colonyNetwork, MINER1, DEFAULT_STAKE);
- const tokenLockingAddress = await colonyNetwork.getTokenLocking();
- const tokenLocking = await ITokenLocking.at(tokenLockingAddress);
- await clnyToken.approve(tokenLocking.address, DEFAULT_STAKE, { from: MINER1 });
- await tokenLocking.methods["deposit(address,uint256,bool)"](clnyToken.address, DEFAULT_STAKE, true, { from: MINER1 });
- const tx = colonyNetwork.stakeForMining(DEFAULT_STAKE, { from: MINER1 });
-
- if (await isXdai()) {
- await tx;
- } else {
- await checkErrorRevert(tx, "colony-only-valid-on-mining-chain-or-during-setup");
- }
- });
-
it("should not make 0-value transfers to 'burn' unneeded mining rewards on xdai", async function () {
- if (!(await isXdai())) {
- // We don't mine anywhere else, so skip
- this.skip();
- }
await giveUserCLNYTokensAndStake(colonyNetwork, MINER1, MIN_STAKE);
await advanceMiningCycleNoContest({ colonyNetwork, test: this });
@@ -172,24 +148,5 @@ contract("Contract Storage", (accounts) => {
await expectEvent(tx, "Transfer(address indexed,address indexed,uint256)", [tokenAuction.address, metaColony.address, receivedTotal]);
}
});
-
- it("reputation mining chain can be changed on non-mining chain", async function () {
- if (await isXdai()) {
- // Not appropriate test on xdai
- this.skip();
- }
-
- const oldChainId = await colonyNetwork.getMiningChainId();
-
- const otherChainId = oldChainId + 1;
- await metaColony.initialiseReputationMining(otherChainId, ethers.constants.HashZero, 0);
-
- const newChainId = await colonyNetwork.getMiningChainId();
- expect(newChainId).to.eq.BN(oldChainId + 1);
- });
-
- it.skip("reputation mining chain can be changed on mining chain", async () => {
- // Not a test, or contract code, that has been written yet
- });
});
});
diff --git a/test/truffle-fixture.js b/test/truffle-fixture.js
index bb22dafa57..22cf279556 100644
--- a/test/truffle-fixture.js
+++ b/test/truffle-fixture.js
@@ -27,6 +27,7 @@ const ColonyNetworkSkills = artifacts.require("ColonyNetworkSkills");
const IColonyNetwork = artifacts.require("IColonyNetwork");
const ENSRegistry = artifacts.require("ENSRegistry");
+const LiFiFacetProxyMock = artifacts.require("LiFiFacetProxyMock");
const ReputationMiningCycle = artifacts.require("ReputationMiningCycle");
const ReputationMiningCycleRespond = artifacts.require("ReputationMiningCycleRespond");
@@ -67,6 +68,7 @@ const assert = require("assert");
const ethers = require("ethers");
const { soliditySha3 } = require("web3-utils");
const truffleContract = require("@truffle/contract");
+const { setCode } = require("@nomicfoundation/hardhat-network-helpers");
const createXABI = require("../lib/createx/artifacts/src/ICreateX.sol/ICreateX.json");
const { resetAlreadyDeployedVersionTracking } = require("../scripts/deployOldUpgradeableVersion");
@@ -92,6 +94,15 @@ module.exports = async () => {
return;
}
+ const chainId = await getChainId();
+ const miningChainId = parseInt(process.env.MINING_CHAIN_ID, 10) || chainId;
+
+ if (chainId !== miningChainId) {
+ console.log("On non-mining chain, so deploy proxy infrastructure");
+ await hre.run("deploy-proxy-network");
+ return;
+ }
+
await deployContracts();
await setupColonyNetwork();
await setupColony();
@@ -181,6 +192,20 @@ async function setupColonyNetwork() {
const etherRouter = await EtherRouterCreate3.at(tx.logs.filter((log) => log.event === "ContractCreation")[0].args.newContract);
EtherRouter.setAsDeployed(etherRouter);
+ // Deploy LiFiMock to LiFi address
+ try {
+ await setCode("0x1231DEB6f5749EF6cE6943a275A1D3E7486F4EaE", LiFiFacetProxyMock.deployedBytecode);
+ } catch (error) {
+ if (error.message.includes("OnlyHardhatNetworkError")) {
+ await new Promise(function (resolve) {
+ web3.provider.send(
+ { method: "evm_setCode", params: ["0x1231DEB6f5749EF6cE6943a275A1D3E7486F4EaE", LiFiFacetProxyMock.deployedBytecode] },
+ resolve,
+ );
+ });
+ }
+ }
+
await setupUpgradableColonyNetwork(
etherRouter,
resolver,