Commit 7c0661e1 authored by Diego's avatar Diego Committed by GitHub

feat/interop: create `StaticConfig` lib (#10591)

* contracts-bedrock: create StaticConfig lib

* contracts-bedrock: fix StaticConfig

* contracts-bedrock: create diff tests for StaticConfig

* contracts-bedrock: rename gas paying token methods in StaticConfig

* contracts-bedrock: add decoding tests for StaticConfig

* contracts-bedrock: refactor encodeGasPayingToken

* contracts-bedrock: define uint256Type for differential testing

* contracts-bedrock: fix missing line in differential-testing

* contracts-bedrock: return packed in utils

* contracts-bedrock: define args as global vars in differential-testing

* contracts-bedrock: use Test instead of CommonTest in tests for StaticConfig

* contracts-bedrock: improve args for encodeGasPayingToken in diff testing

* contracts-bedrock: update sol version for StaticConfig to ^0.8.0
parent 6c43d912
...@@ -38,6 +38,15 @@ var ( ...@@ -38,6 +38,15 @@ var (
uint32Type, _ = abi.NewType("uint32", "", nil) uint32Type, _ = abi.NewType("uint32", "", nil)
// Plain address type
addressType, _ = abi.NewType("address", "", nil)
// Plain uint8 type
uint8Type, _ = abi.NewType("uint8", "", nil)
// Plain uint256 type
uint256Type, _ = abi.NewType("uint256", "", nil)
// Decoded nonce tuple (nonce, version) // Decoded nonce tuple (nonce, version)
decodedNonce, _ = abi.NewType("tuple", "DecodedNonce", []abi.ArgumentMarshaling{ decodedNonce, _ = abi.NewType("tuple", "DecodedNonce", []abi.ArgumentMarshaling{
{Name: "nonce", Type: "uint256"}, {Name: "nonce", Type: "uint256"},
...@@ -82,6 +91,17 @@ var ( ...@@ -82,6 +91,17 @@ var (
cannonMemoryProofArgs = abi.Arguments{ cannonMemoryProofArgs = abi.Arguments{
{Name: "encodedCannonMemoryProof", Type: cannonMemoryProof}, {Name: "encodedCannonMemoryProof", Type: cannonMemoryProof},
} }
// Gas paying token tuple (address, uint8, bytes32, bytes32)
gasPayingTokenArgs = abi.Arguments{
{Name: "token", Type: addressType},
{Name: "decimals", Type: uint8Type},
{Name: "name", Type: fixedBytes},
{Name: "symbol", Type: fixedBytes},
}
// Dependency tuple (uint256)
dependencyArgs = abi.Arguments{{Name: "chainId", Type: uint256Type}}
) )
func DiffTestUtils() { func DiffTestUtils() {
...@@ -388,6 +408,37 @@ func DiffTestUtils() { ...@@ -388,6 +408,37 @@ func DiffTestUtils() {
packed, err := decodedScalars.Pack(scalars.BaseFeeScalar, scalars.BlobBaseFeeScalar) packed, err := decodedScalars.Pack(scalars.BaseFeeScalar, scalars.BlobBaseFeeScalar)
checkErr(err, "Error encoding output") checkErr(err, "Error encoding output")
fmt.Print(hexutil.Encode(packed))
case "encodeGasPayingToken":
// Parse input arguments
token := common.HexToAddress(args[1])
decimals, err := strconv.ParseUint(args[2], 10, 8)
checkErr(err, "Error decoding decimals")
name := common.HexToHash(args[3])
symbol := common.HexToHash(args[4])
// Encode gas paying token
encoded, err := gasPayingTokenArgs.Pack(token, uint8(decimals), name, symbol)
checkErr(err, "Error encoding gas paying token")
// Pack encoded gas paying token
packed, err := bytesArgs.Pack(&encoded)
checkErr(err, "Error encoding output")
fmt.Print(hexutil.Encode(packed))
case "encodeDependency":
// Parse input arguments
chainId, ok := new(big.Int).SetString(args[1], 10)
checkOk(ok)
// Encode dependency
encoded, err := dependencyArgs.Pack(chainId)
checkErr(err, "Error encoding dependency")
// Pack encoded dependency
packed, err := bytesArgs.Pack(&encoded)
checkErr(err, "Error encoding output")
fmt.Print(hexutil.Encode(packed)) fmt.Print(hexutil.Encode(packed))
default: default:
panic(fmt.Errorf("Unknown command: %s", args[0])) panic(fmt.Errorf("Unknown command: %s", args[0]))
......
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
/// @title StaticConfig
/// @notice Library for encoding and decoding static configuration data.
library StaticConfig {
/// @notice Encodes the static configuration data for setting a gas paying token.
/// @param _token Address of the gas paying token.
/// @param _decimals Number of decimals for the gas paying token.
/// @param _name Name of the gas paying token.
/// @param _symbol Symbol of the gas paying token.
/// @return Encoded static configuration data.
function encodeSetGasPayingToken(
address _token,
uint8 _decimals,
bytes32 _name,
bytes32 _symbol
)
internal
pure
returns (bytes memory)
{
return abi.encode(_token, _decimals, _name, _symbol);
}
/// @notice Decodes the static configuration data for setting a gas paying token.
/// @param _data Encoded static configuration data.
/// @return Decoded gas paying token data (token address, decimals, name, symbol).
function decodeSetGasPayingToken(bytes memory _data) internal pure returns (address, uint8, bytes32, bytes32) {
return abi.decode(_data, (address, uint8, bytes32, bytes32));
}
/// @notice Encodes the static configuration data for adding a dependency.
/// @param _chainId Chain ID of the dependency to add.
/// @return Encoded static configuration data.
function encodeAddDependency(uint256 _chainId) internal pure returns (bytes memory) {
return abi.encode(_chainId);
}
/// @notice Decodes the static configuration data for adding a dependency.
/// @param _data Encoded static configuration data.
/// @return Decoded chain ID of the dependency to add.
function decodeAddDependency(bytes memory _data) internal pure returns (uint256) {
return abi.decode(_data, (uint256));
}
/// @notice Encodes the static configuration data for removing a dependency.
/// @param _chainId Chain ID of the dependency to remove.
/// @return Encoded static configuration data.
function encodeRemoveDependency(uint256 _chainId) internal pure returns (bytes memory) {
return abi.encode(_chainId);
}
/// @notice Decodes the static configuration data for removing a dependency.
/// @param _data Encoded static configuration data.
/// @return Decoded chain ID of the dependency to remove.
function decodeRemoveDependency(bytes memory _data) internal pure returns (uint256) {
return abi.decode(_data, (uint256));
}
}
// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;
// Testing utilities
import { Test } from "forge-std/Test.sol";
import { FFIInterface } from "test/setup/FFIInterface.sol";
// Target contract
import { StaticConfig } from "src/libraries/StaticConfig.sol";
contract StaticConfig_Test is Test {
FFIInterface constant ffi = FFIInterface(address(uint160(uint256(keccak256(abi.encode("optimism.ffi"))))));
function setUp() public {
vm.etch(address(ffi), vm.getDeployedCode("FFIInterface.sol:FFIInterface"));
vm.label(address(ffi), "FFIInterface");
}
/// @dev Tests set gas paying token encoding.
function testDiff_encodeSetGasPayingToken_succeeds(
address _token,
uint8 _decimals,
bytes32 _name,
bytes32 _symbol
)
external
{
bytes memory encoding = StaticConfig.encodeSetGasPayingToken(_token, _decimals, _name, _symbol);
bytes memory _encoding = ffi.encodeGasPayingToken(_token, _decimals, _name, _symbol);
assertEq(encoding, _encoding);
}
/// @dev Tests set gas paying token decoding.
function test_decodeSetGasPayingToken_succeeds(
address _token,
uint8 _decimals,
bytes32 _name,
bytes32 _symbol
)
external
{
bytes memory encoding = ffi.encodeGasPayingToken(_token, _decimals, _name, _symbol);
(address token, uint8 decimals, bytes32 name, bytes32 symbol) = StaticConfig.decodeSetGasPayingToken(encoding);
assertEq(token, _token);
assertEq(decimals, _decimals);
assertEq(name, _name);
assertEq(symbol, _symbol);
}
/// @dev Tests add dependency encoding.
function testDiff_encodeAddDependency_succeeds(uint256 _chainId) external {
bytes memory encoding = StaticConfig.encodeAddDependency(_chainId);
bytes memory _encoding = ffi.encodeDependency(_chainId);
assertEq(encoding, _encoding);
}
/// @dev Tests add dependency decoding.
function test_decodeAddDependency_succeeds(uint256 _chainId) external {
bytes memory encoding = ffi.encodeDependency(_chainId);
uint256 chainId = StaticConfig.decodeAddDependency(encoding);
assertEq(chainId, _chainId);
}
/// @dev Tests remove dependency encoding.
function testDiff_encodeRemoveDependency_succeeds(uint256 _chainId) external {
bytes memory encoding = StaticConfig.encodeRemoveDependency(_chainId);
bytes memory _encoding = ffi.encodeDependency(_chainId);
assertEq(encoding, _encoding);
}
/// @dev Tests remove dependency decoding.
function test_decodeRemoveDependency_succeeds(uint256 _chainId) external {
bytes memory encoding = ffi.encodeDependency(_chainId);
uint256 chainId = StaticConfig.decodeRemoveDependency(encoding);
assertEq(chainId, _chainId);
}
}
...@@ -264,4 +264,37 @@ contract FFIInterface { ...@@ -264,4 +264,37 @@ contract FFIInterface {
bytes memory result = vm.ffi(cmds); bytes memory result = vm.ffi(cmds);
return abi.decode(result, (uint32, uint32)); return abi.decode(result, (uint32, uint32));
} }
function encodeGasPayingToken(
address _token,
uint8 _decimals,
bytes32 _name,
bytes32 _symbol
)
external
returns (bytes memory)
{
string[] memory cmds = new string[](7);
cmds[0] = "scripts/go-ffi/go-ffi";
cmds[1] = "diff";
cmds[2] = "encodeGasPayingToken";
cmds[3] = vm.toString(_token);
cmds[4] = vm.toString(_decimals);
cmds[5] = vm.toString(_name);
cmds[6] = vm.toString(_symbol);
bytes memory result = vm.ffi(cmds);
return abi.decode(result, (bytes));
}
function encodeDependency(uint256 _chainId) external returns (bytes memory) {
string[] memory cmds = new string[](4);
cmds[0] = "scripts/go-ffi/go-ffi";
cmds[1] = "diff";
cmds[2] = "encodeDependency";
cmds[3] = vm.toString(_chainId);
bytes memory result = vm.ffi(cmds);
return abi.decode(result, (bytes));
}
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment