Skip to content

Commit

Permalink
Merge pull request #12 from echonft/feature/escrow
Browse files Browse the repository at this point in the history
Revamped contract for escrow
  • Loading branch information
GabrielCartier authored Jul 15, 2024
2 parents abe69e1 + fb97001 commit 4dbf7b0
Show file tree
Hide file tree
Showing 69 changed files with 6,271 additions and 1,996 deletions.
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_API_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.

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

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

fuzz_runs = 1000

[profile.ci]
verbosity = 4

gas_reports = ["Echo"]

# Config
[rpc_endpoints]
sepolia = "${SEPOLIA_RPC_URL}"
blast_sepolia = "${BLAST_SEPOLIA_RPC_URL}"
blast = "${BLAST_RPC_URL}"

[etherscan]
sepolia = { key = "${ETHERSCAN_API_KEY}" }
blast_sepolia = { key = "${BLASTSCAN_API_KEY}", url="https://api-sepolia.blastscan.io/api" }
blast = { key = "${BLASTSCAN_API_KEY}", url="https://api.blastscan.io/api" }
55 changes: 55 additions & 0 deletions lib/blast/IBlast.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.18;

enum YieldMode {
AUTOMATIC,
VOID,
CLAIMABLE
}

enum GasMode {
VOID,
CLAIMABLE
}

interface IBlast {
// configure
function configureContract(address contractAddress, YieldMode _yield, GasMode gasMode, address governor) external;
function configure(YieldMode _yield, GasMode gasMode, address governor) external;

// base configuration options
function configureClaimableYield() external;
function configureClaimableYieldOnBehalf(address contractAddress) external;
function configureAutomaticYield() external;
function configureAutomaticYieldOnBehalf(address contractAddress) external;
function configureVoidYield() external;
function configureVoidYieldOnBehalf(address contractAddress) external;
function configureClaimableGas() external;
function configureClaimableGasOnBehalf(address contractAddress) external;
function configureVoidGas() external;
function configureVoidGasOnBehalf(address contractAddress) external;
function configureGovernor(address _governor) external;
function configureGovernorOnBehalf(address _newGovernor, address contractAddress) external;

// claim yield
function claimYield(address contractAddress, address recipientOfYield, uint256 amount) external returns (uint256);
function claimAllYield(address contractAddress, address recipientOfYield) external returns (uint256);

// claim gas
function claimAllGas(address contractAddress, address recipientOfGas) external returns (uint256);
function claimGasAtMinClaimRate(address contractAddress, address recipientOfGas, uint256 minClaimRateBips)
external
returns (uint256);
function claimMaxGas(address contractAddress, address recipientOfGas) external returns (uint256);
function claimGas(address contractAddress, address recipientOfGas, uint256 gasToClaim, uint256 gasSecondsToConsume)
external
returns (uint256);

// read functions
function readClaimableYield(address contractAddress) external view returns (uint256);
function readYieldConfiguration(address contractAddress) external view returns (uint8);
function readGasParams(address contractAddress)
external
view
returns (uint256 etherSeconds, uint256 etherBalance, uint256 lastUpdated, GasMode);
}
7 changes: 7 additions & 0 deletions lib/blast/IBlastPoints.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.18;

interface IBlastPoints {
function configurePointsOperator(address operator) external;
function configurePointsOperatorOnBehalf(address contractAddress, address operator) external;
}
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;
}
}
Loading

1 comment on commit 4dbf7b0

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Coverage for this commit

73.11%

Coverage Report
FileStmtsBranchesFuncsLinesUncovered Lines
src
   Admin.sol100%100%100%100%
   Banker.sol100%100%100%100%
   Echo.sol100%100%100%100%
   EchoBlast.sol0%100%0%0%12–14, 18
   EchoState.sol100%100%100%100%
src/escrow
   Escrow.sol100%100%100%100%
   EscrowHandler.sol100%100%100%100%
src/wormhole
   WormholeGovernance.sol0%0%0%0%100, 12, 12, 12–13, 15, 15, 15–16, 18, 18, 18–19, 21–23, 96–97, 99, 99, 99
   WormholeState.sol0%0%0%0%33, 37, 41, 54, 54, 54–55, 57, 57, 57–58, 61, 65, 69
test/mock
   YieldMock.sol0%0%0%0%10, 10, 10, 12–13, 17, 21

Please sign in to comment.