feat(libraries): add byte slicing and multi-hop path encoding
This commit is contained in:
1 parent
25bb567003
commit
54b5377369
2 files changed
+90
No files matched your search
@@ -0,0 +1,53 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity 0.8.36;
|
||||
|
||||
/// @title Slicing and word reads over tightly packed calldata paths.
|
||||
library BytesLib {
|
||||
function slice(bytes memory source, uint256 start, uint256 length) internal pure returns (bytes memory) {
|
||||
require(length + 31 >= length, "BytesLib: SLICE_OVERFLOW");
|
||||
require(source.length >= start + length, "BytesLib: SLICE_OOB");
|
||||
|
||||
bytes memory result;
|
||||
assembly {
|
||||
switch iszero(length)
|
||||
case 0 {
|
||||
result := mload(0x40)
|
||||
let lengthmod := and(length, 31)
|
||||
let mc := add(add(result, lengthmod), mul(0x20, iszero(lengthmod)))
|
||||
let end := add(mc, length)
|
||||
for {
|
||||
let cc := add(add(add(source, lengthmod), mul(0x20, iszero(lengthmod))), start)
|
||||
} lt(mc, end) {
|
||||
mc := add(mc, 0x20)
|
||||
cc := add(cc, 0x20)
|
||||
} { mstore(mc, mload(cc)) }
|
||||
mstore(result, length)
|
||||
mstore(0x40, and(add(mc, 31), not(31)))
|
||||
}
|
||||
default {
|
||||
result := mload(0x40)
|
||||
mstore(result, 0)
|
||||
mstore(0x40, add(result, 0x20))
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function toAddress(bytes memory source, uint256 start) internal pure returns (address) {
|
||||
require(source.length >= start + 20, "BytesLib: ADDRESS_OOB");
|
||||
address result;
|
||||
assembly {
|
||||
result := div(mload(add(add(source, 0x20), start)), 0x1000000000000000000000000)
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function toUint24(bytes memory source, uint256 start) internal pure returns (uint24) {
|
||||
require(source.length >= start + 3, "BytesLib: UINT24_OOB");
|
||||
uint24 result;
|
||||
assembly {
|
||||
result := mload(add(add(source, 0x3), start))
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity 0.8.36;
|
||||
|
||||
import {BytesLib} from "./BytesLib.sol";
|
||||
|
||||
/// @title Encoding of multi-hop swap paths as packed token/fee/token sequences.
|
||||
library Path {
|
||||
using BytesLib for bytes;
|
||||
|
||||
uint256 private constant addrSize = 20;
|
||||
uint256 private constant feeSize = 3;
|
||||
uint256 private constant nextOffset = addrSize + feeSize;
|
||||
uint256 private constant popOffset = nextOffset + addrSize;
|
||||
uint256 private constant multiplePoolsMinLength = popOffset + nextOffset;
|
||||
|
||||
function hasMultiplePools(bytes memory path) internal pure returns (bool) {
|
||||
return path.length >= multiplePoolsMinLength;
|
||||
}
|
||||
|
||||
function numPools(bytes memory path) internal pure returns (uint256) {
|
||||
return (path.length - addrSize) / nextOffset;
|
||||
}
|
||||
|
||||
function decodeFirstPool(bytes memory path) internal pure returns (address tokenA, address tokenB, uint24 fee) {
|
||||
tokenA = path.toAddress(0);
|
||||
fee = path.toUint24(addrSize);
|
||||
tokenB = path.toAddress(nextOffset);
|
||||
}
|
||||
|
||||
function getFirstPool(bytes memory path) internal pure returns (bytes memory) {
|
||||
return path.slice(0, popOffset);
|
||||
}
|
||||
|
||||
function skipToken(bytes memory path) internal pure returns (bytes memory) {
|
||||
return path.slice(nextOffset, path.length - nextOffset);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user