Helpers to collect signatures for erc20-to-native and AMB (#576)
This commit is contained in:
parent
44c84e4be0
commit
08fd1e0129
|
@ -0,0 +1,65 @@
|
|||
pragma solidity 0.4.24;
|
||||
|
||||
interface IHomeBridge {
|
||||
function numMessagesSigned(bytes32 _message) external view returns (uint256);
|
||||
function isAlreadyProcessed(uint256 _number) external pure returns (bool);
|
||||
function signature(bytes32 _hash, uint256 _index) external view returns (bytes memory);
|
||||
}
|
||||
|
||||
contract Helper {
|
||||
function unpackSignature(bytes memory _signature) internal pure returns (bytes32 r, bytes32 s, uint8 v) {
|
||||
require(_signature.length == 65);
|
||||
|
||||
assembly {
|
||||
r := mload(add(_signature, 0x20))
|
||||
s := mload(add(_signature, 0x40))
|
||||
v := mload(add(_signature, 0x41))
|
||||
}
|
||||
return (r, s, v);
|
||||
}
|
||||
}
|
||||
|
||||
contract AMBBridgeHelper is Helper {
|
||||
address public owner;
|
||||
IHomeBridge public ambBridge;
|
||||
|
||||
constructor(address _homeBridge) public {
|
||||
owner = msg.sender;
|
||||
ambBridge = IHomeBridge(_homeBridge);
|
||||
}
|
||||
|
||||
function getSignatures(bytes _message) external view returns (bytes memory) {
|
||||
bytes32 msgHash = keccak256(abi.encodePacked(_message));
|
||||
uint256 signed = ambBridge.numMessagesSigned(msgHash);
|
||||
|
||||
require(ambBridge.isAlreadyProcessed(signed), "message hasn't been confirmed");
|
||||
|
||||
// recover number of confirmations sent by oracles
|
||||
signed = signed & 0x8fffffffffffffffffffffffffffffffffffffffffff;
|
||||
|
||||
require(signed < 0x100);
|
||||
|
||||
bytes memory signatures = new bytes(1 + signed * 65);
|
||||
|
||||
assembly {
|
||||
mstore8(add(signatures, 32), signed)
|
||||
}
|
||||
|
||||
for (uint256 i = 0; i < signed; i++) {
|
||||
bytes memory sig = ambBridge.signature(msgHash, i);
|
||||
(bytes32 r, bytes32 s, uint8 v) = unpackSignature(sig);
|
||||
assembly {
|
||||
mstore8(add(add(signatures, 33), i), v)
|
||||
mstore(add(add(add(signatures, 33), signed), mul(i, 32)), r)
|
||||
mstore(add(add(add(signatures, 33), mul(signed, 33)), mul(i, 32)), s)
|
||||
}
|
||||
}
|
||||
|
||||
return signatures;
|
||||
}
|
||||
|
||||
function clean() external {
|
||||
require(msg.sender == owner, "not an owner");
|
||||
selfdestruct(owner);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,79 @@
|
|||
pragma solidity 0.4.24;
|
||||
|
||||
interface IHomeErc20ToNativeBridge {
|
||||
function numMessagesSigned(bytes32 _message) external view returns (uint256);
|
||||
function isAlreadyProcessed(uint256 _number) external pure returns (bool);
|
||||
function message(bytes32 _hash) external view returns (bytes memory);
|
||||
function signature(bytes32 _hash, uint256 _index) external view returns (bytes memory);
|
||||
}
|
||||
|
||||
contract Helper {
|
||||
function unpackSignature(bytes memory _signature) internal pure returns (bytes32 r, bytes32 s, uint8 v) {
|
||||
require(_signature.length == 65);
|
||||
|
||||
assembly {
|
||||
r := mload(add(_signature, 0x20))
|
||||
s := mload(add(_signature, 0x40))
|
||||
v := mload(add(_signature, 0x41))
|
||||
}
|
||||
return (r, s, v);
|
||||
}
|
||||
}
|
||||
|
||||
contract Erc20ToNativeBridgeHelper is Helper {
|
||||
address public owner;
|
||||
IHomeErc20ToNativeBridge public bridge;
|
||||
address public foreignBridge;
|
||||
|
||||
constructor(address _homeBridge, address _foreignBridge) public {
|
||||
owner = msg.sender;
|
||||
bridge = IHomeErc20ToNativeBridge(_homeBridge);
|
||||
foreignBridge = _foreignBridge;
|
||||
}
|
||||
|
||||
function getMessage(bytes32 _msgHash) external view returns (bytes memory result) {
|
||||
result = bridge.message(_msgHash);
|
||||
}
|
||||
|
||||
function getMessageHash(address _recipient, uint256 _value, bytes32 _origTxHash) external view returns (bytes32) {
|
||||
bytes32 result = keccak256(abi.encodePacked(_recipient, _value, _origTxHash, foreignBridge));
|
||||
return result;
|
||||
}
|
||||
|
||||
function getSignatures(bytes32 _msgHash) external view returns (bytes memory) {
|
||||
uint256 signed = bridge.numMessagesSigned(_msgHash);
|
||||
|
||||
require(bridge.isAlreadyProcessed(signed), "message hasn't been confirmed");
|
||||
|
||||
// recover number of confirmations sent by oracles
|
||||
signed = signed & 0x8fffffffffffffffffffffffffffffffffffffffffff;
|
||||
|
||||
require(signed < 0x100);
|
||||
|
||||
bytes memory signatures = new bytes(1 + signed * 65);
|
||||
|
||||
assembly {
|
||||
mstore8(add(signatures, 32), signed)
|
||||
}
|
||||
|
||||
for (uint256 i = 0; i < signed; i++) {
|
||||
bytes memory sig = bridge.signature(_msgHash, i);
|
||||
(bytes32 r, bytes32 s, uint8 v) = unpackSignature(sig);
|
||||
assembly {
|
||||
let ptr := add(signatures, 33)
|
||||
mstore8(add(ptr, i), v)
|
||||
ptr := add(ptr, signed)
|
||||
mstore(add(ptr, mul(i, 32)), r)
|
||||
ptr := add(ptr, mul(signed, 32))
|
||||
mstore(add(ptr, mul(i, 32)), s)
|
||||
}
|
||||
}
|
||||
|
||||
return signatures;
|
||||
}
|
||||
|
||||
function clean() external {
|
||||
require(msg.sender == owner, "not an owner");
|
||||
selfdestruct(owner);
|
||||
}
|
||||
}
|
|
@ -24,7 +24,7 @@ const provider = new Web3ProviderEngine()
|
|||
if (process.env.SOLIDITY_COVERAGE === 'true') {
|
||||
global.coverageSubprovider = new CoverageSubprovider(artifactAdapter, defaultFromAddress, {
|
||||
isVerbose,
|
||||
ignoreFilesGlobs: ['**/Migrations.sol', '**/node_modules/**', '**/mocks/**', '**/interfaces/**']
|
||||
ignoreFilesGlobs: ['**/Migrations.sol', '**/node_modules/**', '**/mocks/**', '**/interfaces/**', '**/helpers/**']
|
||||
})
|
||||
provider.addProvider(global.coverageSubprovider)
|
||||
const ganacheSubprovider = new GanacheSubprovider({
|
||||
|
|
Loading…
Reference in New Issue