Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Revamped contract for escrow #12

Merged
merged 29 commits into from
Jul 15, 2024
Merged
Show file tree
Hide file tree
Changes from 23 commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
ac1c874
WIP started working on Wormhole integration
GabrielCartier Apr 9, 2024
c3b5309
added mint script
GabrielCartier Apr 10, 2024
c3f2c67
WIP Wormhole POC
GabrielCartier Apr 10, 2024
f7c595f
WIP Added bridge test
GabrielCartier Apr 10, 2024
824c8cd
testing
GabrielCartier Apr 10, 2024
4f30516
WIP update for EVM wormhole
GabrielCartier May 6, 2024
0942ff3
started cleaning code for wormhole version
GabrielCartier May 7, 2024
e0d9b67
compiling works
GabrielCartier May 7, 2024
233e1c1
added accept and execute same chain
GabrielCartier May 7, 2024
d5a1230
pretteir
GabrielCartier May 7, 2024
d037ea7
added create offer tests
0xjohnnycagewins May 10, 2024
784533f
cleaned code and fixed tests
GabrielCartier May 10, 2024
54eb97c
finished testing create offer
GabrielCartier May 10, 2024
ebacc3e
Tested accept offer
GabrielCartier May 10, 2024
3541e86
Testing almost done
GabrielCartier May 11, 2024
df4ce00
Added redeem
GabrielCartier May 13, 2024
a022ccb
Added creation paused function
GabrielCartier May 13, 2024
97463f2
Removed dead code, added tests
GabrielCartier May 13, 2024
0d56130
removed dead code
GabrielCartier May 13, 2024
200bc2e
added more tests
GabrielCartier May 13, 2024
b96168b
slither fix
GabrielCartier May 13, 2024
0996a31
removed potential re-entrancy issues
GabrielCartier May 13, 2024
be33a37
added events
GabrielCartier May 13, 2024
40b8292
Added blast support
GabrielCartier May 13, 2024
9eeb04c
updated scripts
GabrielCartier May 14, 2024
71aa844
Small update
GabrielCartier May 27, 2024
927db1a
Added OfferRedeemed event
GabrielCartier May 27, 2024
9f076f3
fixed scripts
GabrielCartier Jun 6, 2024
fb97001
Merge pull request #13 from echonft/feature/blast
GabrielCartier Jul 15, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ MAINNET_RPC_URL=
SEPOLIA_RPC_URL=
PRIVATE_KEY=
MAINNET_PRIVATE_KEY=
ETHERSCAN_KEY=
ETHERSCAN_KEY=
1 change: 1 addition & 0 deletions .idea/echo-contracts.iml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 13 additions & 0 deletions .idea/inspectionProfiles/Project_Default.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

25 changes: 25 additions & 0 deletions .idea/watcherTasks.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions foundry.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ src = 'src'
out = 'out'
libs = ['lib']

remappings = [
"forge-std/=lib/forge-std/src/"
]

fuzz_runs = 1000

[profile.ci]
Expand Down
179 changes: 179 additions & 0 deletions lib/wormhole/BytesLib.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
// SPDX-License-Identifier: Unlicense
/*
* @title Solidity Bytes Arrays Utils
* @author Gonçalo Sá <[email protected]>
*
* @dev Bytes tightly packed arrays utility library for ethereum contracts written in Solidity.
* This is a reduced version of the library.
*/
pragma solidity >=0.8.0 <0.9.0;

library BytesLib {
uint256 private constant freeMemoryPtr = 0x40;
uint256 private constant maskModulo32 = 0x1f;
/**
* Size of word read by `mload` instruction.
*/
uint256 private constant memoryWord = 32;
uint256 internal constant uint8Size = 1;
uint256 internal constant uint16Size = 2;
uint256 internal constant uint32Size = 4;
uint256 internal constant uint64Size = 8;
uint256 internal constant uint128Size = 16;
uint256 internal constant uint256Size = 32;
uint256 internal constant addressSize = 20;
/**
* Bits in 12 bytes.
*/
uint256 private constant bytes12Bits = 96;

function slice(bytes memory buffer, uint256 startIndex, uint256 length) internal pure returns (bytes memory) {
unchecked {
require(length + 31 >= length, "slice_overflow");
}
require(buffer.length >= startIndex + length, "slice_outOfBounds");

bytes memory tempBytes;

assembly ("memory-safe") {
// Get a location of some free memory and store it in tempBytes as
// Solidity does for memory variables.
tempBytes := mload(freeMemoryPtr)

switch iszero(length)
case 0 {
// The first word of the slice result is potentially a partial
// word read from the original array. To read it, we calculate
// the length of that partial word and start copying that many
// bytes into the array. The first word we copy will start with
// data we don't care about, but the last `lengthmod` bytes will
// land at the beginning of the contents of the new array. When
// we're done copying, we overwrite the full first word with
// the actual length of the slice.
let lengthmod := and(length, maskModulo32)
// The multiplication in the next line is necessary
// because when slicing multiples of 32 bytes (lengthmod == 0)
// the following copy loop was copying the origin's length
// and then ending prematurely not copying everything it should.
let startOffset := add(lengthmod, mul(memoryWord, iszero(lengthmod)))

let dst := add(tempBytes, startOffset)
let end := add(dst, length)

for { let src := add(add(buffer, startOffset), startIndex) } lt(dst, end) {
dst := add(dst, memoryWord)
src := add(src, memoryWord)
} { mstore(dst, mload(src)) }

// Update free-memory pointer
// allocating the array padded to 32 bytes like the compiler does now
// Note that negating bitwise the `maskModulo32` produces a mask that aligns addressing to 32 bytes.
mstore(freeMemoryPtr, and(add(dst, maskModulo32), not(maskModulo32)))
}
//if we want a zero-length slice let's just return a zero-length array
default { mstore(freeMemoryPtr, add(tempBytes, memoryWord)) }

// Store the length of the buffer
// We need to do it even if the length is zero because Solidity does not garbage collect
mstore(tempBytes, length)
}

return tempBytes;
}

function toAddress(bytes memory buffer, uint256 startIndex) internal pure returns (address) {
require(buffer.length >= startIndex + addressSize, "toAddress_outOfBounds");
address tempAddress;

assembly ("memory-safe") {
// We want to shift into the lower 12 bytes and leave the upper 12 bytes clear.
tempAddress := shr(bytes12Bits, mload(add(add(buffer, memoryWord), startIndex)))
}

return tempAddress;
}

function toUint8(bytes memory buffer, uint256 startIndex) internal pure returns (uint8) {
require(buffer.length > startIndex, "toUint8_outOfBounds");

// Note that `endIndex == startOffset` for a given buffer due to the 32 bytes at the start that store the length.
uint256 startOffset = startIndex + uint8Size;
uint8 tempUint;
assembly ("memory-safe") {
tempUint := mload(add(buffer, startOffset))
}
return tempUint;
}

function toUint16(bytes memory buffer, uint256 startIndex) internal pure returns (uint16) {
uint256 endIndex = startIndex + uint16Size;
require(buffer.length >= endIndex, "toUint16_outOfBounds");

uint16 tempUint;
assembly ("memory-safe") {
// Note that `endIndex == startOffset` for a given buffer due to the 32 bytes at the start that store the length.
tempUint := mload(add(buffer, endIndex))
}
return tempUint;
}

function toUint32(bytes memory buffer, uint256 startIndex) internal pure returns (uint32) {
uint256 endIndex = startIndex + uint32Size;
require(buffer.length >= endIndex, "toUint32_outOfBounds");

uint32 tempUint;
assembly ("memory-safe") {
// Note that `endIndex == startOffset` for a given buffer due to the 32 bytes at the start that store the length.
tempUint := mload(add(buffer, endIndex))
}
return tempUint;
}

function toUint64(bytes memory buffer, uint256 startIndex) internal pure returns (uint64) {
uint256 endIndex = startIndex + uint64Size;
require(buffer.length >= endIndex, "toUint64_outOfBounds");

uint64 tempUint;
assembly ("memory-safe") {
// Note that `endIndex == startOffset` for a given buffer due to the 32 bytes at the start that store the length.
tempUint := mload(add(buffer, endIndex))
}
return tempUint;
}

function toUint128(bytes memory buffer, uint256 startIndex) internal pure returns (uint128) {
uint256 endIndex = startIndex + uint128Size;
require(buffer.length >= endIndex, "toUint128_outOfBounds");

uint128 tempUint;
assembly ("memory-safe") {
// Note that `endIndex == startOffset` for a given buffer due to the 32 bytes at the start that store the length.
tempUint := mload(add(buffer, endIndex))
}
return tempUint;
}

function toUint256(bytes memory buffer, uint256 startIndex) internal pure returns (uint256) {
uint256 endIndex = startIndex + uint256Size;
require(buffer.length >= endIndex, "toUint256_outOfBounds");

uint256 tempUint;
assembly ("memory-safe") {
// Note that `endIndex == startOffset` for a given buffer due to the 32 bytes at the start that store the length.
tempUint := mload(add(buffer, endIndex))
}
return tempUint;
}

function toBytes32(bytes memory buffer, uint256 startIndex) internal pure returns (bytes32) {
uint256 endIndex = startIndex + uint256Size;
require(buffer.length >= endIndex, "toBytes32_outOfBounds");

bytes32 tempBytes32;
assembly ("memory-safe") {
// Note that `endIndex == startOffset` for a given buffer due to the 32 bytes at the start that store the length.
tempBytes32 := mload(add(buffer, endIndex))
}
return tempBytes32;
}
}
146 changes: 146 additions & 0 deletions lib/wormhole/IWormhole.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
// SPDX-License-Identifier: Apache 2
pragma solidity ^0.8.18;

interface IWormhole {
struct GuardianSet {
address[] keys;
uint32 expirationTime;
}

struct Signature {
bytes32 r;
bytes32 s;
uint8 v;
uint8 guardianIndex;
}

struct VM {
uint8 version;
uint32 timestamp;
uint32 nonce;
uint16 emitterChainId;
bytes32 emitterAddress;
uint64 sequence;
uint8 consistencyLevel;
bytes payload;
uint32 guardianSetIndex;
Signature[] signatures;
bytes32 hash;
}

struct ContractUpgrade {
bytes32 module;
uint8 action;
uint16 chain;
address newContract;
}

struct GuardianSetUpgrade {
bytes32 module;
uint8 action;
uint16 chain;
GuardianSet newGuardianSet;
uint32 newGuardianSetIndex;
}

struct SetMessageFee {
bytes32 module;
uint8 action;
uint16 chain;
uint256 messageFee;
}

struct TransferFees {
bytes32 module;
uint8 action;
uint16 chain;
uint256 amount;
bytes32 recipient;
}

struct RecoverChainId {
bytes32 module;
uint8 action;
uint256 evmChainId;
uint16 newChainId;
}

event LogMessagePublished(
address indexed sender, uint64 sequence, uint32 nonce, bytes payload, uint8 consistencyLevel
);
event ContractUpgraded(address indexed oldContract, address indexed newContract);
event GuardianSetAdded(uint32 indexed index);

function publishMessage(uint32 nonce, bytes memory payload, uint8 consistencyLevel)
external
payable
returns (uint64 sequence);

function initialize() external;

function parseAndVerifyVM(bytes calldata encodedVM)
external
view
returns (VM memory vm, bool valid, string memory reason);

function verifyVM(VM memory vm) external view returns (bool valid, string memory reason);

function verifySignatures(bytes32 hash, Signature[] memory signatures, GuardianSet memory guardianSet)
external
pure
returns (bool valid, string memory reason);

function parseVM(bytes memory encodedVM) external pure returns (VM memory vm);

function quorum(uint256 numGuardians) external pure returns (uint256 numSignaturesRequiredForQuorum);

function getGuardianSet(uint32 index) external view returns (GuardianSet memory);

function getCurrentGuardianSetIndex() external view returns (uint32);

function getGuardianSetExpiry() external view returns (uint32);

function governanceActionIsConsumed(bytes32 hash) external view returns (bool);

function isInitialized(address impl) external view returns (bool);

function chainId() external view returns (uint16);

function isFork() external view returns (bool);

function governanceChainId() external view returns (uint16);

function governanceContract() external view returns (bytes32);

function messageFee() external view returns (uint256);

function evmChainId() external view returns (uint256);

function nextSequence(address emitter) external view returns (uint64);

function parseContractUpgrade(bytes memory encodedUpgrade) external pure returns (ContractUpgrade memory cu);

function parseGuardianSetUpgrade(bytes memory encodedUpgrade)
external
pure
returns (GuardianSetUpgrade memory gsu);

function parseSetMessageFee(bytes memory encodedSetMessageFee) external pure returns (SetMessageFee memory smf);

function parseTransferFees(bytes memory encodedTransferFees) external pure returns (TransferFees memory tf);

function parseRecoverChainId(bytes memory encodedRecoverChainId)
external
pure
returns (RecoverChainId memory rci);

function submitContractUpgrade(bytes memory _vm) external;

function submitSetMessageFee(bytes memory _vm) external;

function submitNewGuardianSet(bytes memory _vm) external;

function submitTransferFees(bytes memory _vm) external;

function submitRecoverChainId(bytes memory _vm) external;
}
Loading
Loading