generated from PaulRBerg/foundry-template
-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
5ac171c
commit 13f6471
Showing
2 changed files
with
81 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity ^0.8.0; | ||
|
||
library FunctionCodec { | ||
function encodeParams(address contractAddr, bytes4 selector) internal pure returns (bytes24) { | ||
return bytes24(bytes20(contractAddr)) | bytes24(selector) >> 160; | ||
} | ||
|
||
function decodeParams(bytes24 encoded) internal pure returns (address contractAddr, bytes4 selector) { | ||
contractAddr = address(bytes20(encoded)); | ||
selector = bytes4(encoded << 160); | ||
} | ||
|
||
function encodeFunction(function () external returns(string memory) f) internal pure returns (bytes24) { | ||
return encodeParams(f.address, f.selector); | ||
} | ||
|
||
function decodeFunction( | ||
address contractAddr, | ||
bytes4 selector | ||
) | ||
internal | ||
pure | ||
returns (function () external returns(string memory) f) | ||
{ | ||
uint32 s = uint32(selector); | ||
assembly { | ||
f.address := contractAddr | ||
f.selector := s | ||
} | ||
} | ||
|
||
function decodeFunction(bytes24 encoded) internal pure returns (function () external returns(string memory) f) { | ||
(address contractAddr, bytes4 selector) = decodeParams(encoded); | ||
return decodeFunction(contractAddr, selector); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity ^0.8.0; | ||
|
||
import { PRBTest } from "@prb/test/PRBTest.sol"; | ||
import { console2 } from "forge-std/console2.sol"; | ||
import { StdCheats } from "forge-std/StdCheats.sol"; | ||
|
||
import "src/utils/FunctionCodec.sol"; | ||
|
||
contract FunctionCodecTest is PRBTest, StdCheats { | ||
function mockCallback() external pure returns(string memory) { | ||
return "Hello, world!"; | ||
} | ||
|
||
function testEncodeParams() public { | ||
assertEq( | ||
FunctionCodec.encodeParams(address(this), this.mockCallback.selector), | ||
bytes24(abi.encodePacked(address(this), this.mockCallback.selector)) | ||
); | ||
} | ||
|
||
function testDecodeParams() public { | ||
bytes24 encoded = FunctionCodec.encodeParams(address(this), this.mockCallback.selector); | ||
(address contractAddr, bytes4 selector) = FunctionCodec.decodeParams(encoded); | ||
assertEq(contractAddr, address(this)); | ||
assertEq(selector, this.mockCallback.selector); | ||
} | ||
|
||
function testEncodeFunction() public { | ||
bytes24 encoded = FunctionCodec.encodeFunction(this.mockCallback); | ||
assertEq(encoded, bytes24(abi.encodePacked(address(this), this.mockCallback.selector))); | ||
} | ||
|
||
function testDecodeFunction() public { | ||
function () external returns(string memory) f = FunctionCodec.decodeFunction(address(this), this.mockCallback.selector); | ||
assertEq(f(), this.mockCallback()); | ||
} | ||
|
||
function testDecodeFunction2() public { | ||
bytes24 encoded = FunctionCodec.encodeFunction(this.mockCallback); | ||
function () external returns(string memory) f = FunctionCodec.decodeFunction(encoded); | ||
assertEq(f(), this.mockCallback()); | ||
} | ||
} |