Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
965 changes: 491 additions & 474 deletions .gas-snapshot

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion lib/rain.interpreter.interface
4 changes: 2 additions & 2 deletions src/generated/Rainterpreter.pointers.sol
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@
pragma solidity =0.8.25;

/// @dev Hash of the known bytecode.
bytes32 constant BYTECODE_HASH = bytes32(0xfb3f1b21051afed257ddbc45179a15718cc1ef1c2f594b33b0d58e8234ad9f6b);
bytes32 constant BYTECODE_HASH = bytes32(0xa6b8194695aec2caaf40b73cd4e492ee12c82b68f6cb09e771bcd016eb1c1830);

/// @dev The function pointers known to the interpreter for dynamic dispatch.
/// By setting these as a constant they can be inlined into the interpreter
/// and loaded at eval time for very low gas (~100) due to the compiler
/// optimising it to a single `codecopy` to build the in memory bytes array.
bytes constant OPCODE_FUNCTION_POINTERS =
hex"0749077b079f092b09f40a060a180a310a550a890a9a0aab0b4d0b6c0c2a0cda0e1c0f4f0ff1107510861097109710a81135114e1162117b119411a71209125712a512d61324137213c014a7";
hex"075b078d07b1093d0a060a180a2a0a430a670a9b0aac0abd0b5f0b7e0c3c0cec0d700eb20fe510de118011f81209121a121a122b12b812d112e512fe1317132a138c13da1428145914a714f51543162a";
6 changes: 3 additions & 3 deletions src/generated/RainterpreterExpressionDeployer.pointers.sol
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@
pragma solidity =0.8.25;

/// @dev Hash of the known bytecode.
bytes32 constant BYTECODE_HASH = bytes32(0xdc618b20362cbf40d34136f4c0507f0c5f60301abd35a026e32baf4764e0a0da);
bytes32 constant BYTECODE_HASH = bytes32(0x8129e7266bfb3b783324f17acce944c8eceb52114fdc1e752e1e619af4b996a7);

/// @dev The hash of the meta that describes the contract.
bytes32 constant DESCRIBED_BY_META_HASH = bytes32(0xbebc529bcf04714a69fdd6a742560fb243b303b6e4ffdf69b30f0948a47ed0b3);
bytes32 constant DESCRIBED_BY_META_HASH = bytes32(0xa584ea21441427aadd44a19078a8f80abb0563d43e8da2bb0aab9f02a1205398);

/// @dev The function pointers for the integrity check fns.
bytes constant INTEGRITY_FUNCTION_POINTERS =
hex"0de80e660eca1044104e104e10581061107c11221122117e11f61203104e1203104e104e10581044104410441044120d104e104e104e104e10441217123f121710441217123f123f1058120d";
hex"0df80e760eda1054105e105e10681071108c11321132118e12061213105e10681213105e1068105e10681054105410541054121d105e105e105e105e10541227124f122710541227124f124f1068121d";
8 changes: 4 additions & 4 deletions src/generated/RainterpreterParser.pointers.sol
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
pragma solidity =0.8.25;

/// @dev Hash of the known bytecode.
bytes32 constant BYTECODE_HASH = bytes32(0x462087a93e3b043abb176513bfc08f67767019ac3b6ed30880c894a3ec231f66);
bytes32 constant BYTECODE_HASH = bytes32(0x6f543e4dfa04d86b7bb9adbd4f2daf59cafd956a3d1f4d295cb680b8c286ac04);

/// @dev The parse meta that is used to lookup word definitions.
/// The structure of the parse meta is:
Expand All @@ -29,7 +29,7 @@ bytes32 constant BYTECODE_HASH = bytes32(0x462087a93e3b043abb176513bfc08f6776701
/// bit count of the previous bloom filter. If we reach the end of the bloom
/// filters then we have a miss.
bytes constant PARSE_META =
hex"010e000088000000102c00000c8880800d24a0148109008880010000140550a010000d1dbb6302525f2210999fd51671b5110a2139801869a80f00a4ed3f25ba92e12148361e2428c11e089ebd5e07e2359819b5fc9e22d9ace20fe92356143994150b7dfb1509bb6451066c83bf1f5797780c4960e303fa47a905e82f0c1b4efea02024d7751dbfd64113d6a860115832fd1ab8491f1ebe2c7c01d81c842362708d0efdd5d8122466661547b9490477ee1817e0ddd31c3436fb";
hex"010e000088000004102c00000c8880800d24a0148109008880010000140554a010000d1dbb6302525f2211999fd50f6c01da1871b5110a2139801a69a80f00a4ed3f27ba92e12348361e2628c11e089ebd5e07e235981bb5fc9e24d9ace210e92356163994150b7dfb1509bb6451066c83bf215797780c4960e303fa47a905e82f0c1d4efea02224d7751fbfd64115d6a860135832fd1cb8491f20be2c7c01d81c842562708d0efdd5d8142466661747b9490477ee181251471f19e0ddd31e3436fb";

/// @dev The build depth of the parser meta.

Expand All @@ -39,11 +39,11 @@ uint8 constant PARSE_META_BUILD_DEPTH = 2;
/// These positional indexes all map to the same indexes looked up in the parse
/// meta.
bytes constant OPERAND_HANDLER_FUNCTION_POINTERS =
hex"19ca19ca19ca1a9f1bb61bb61bb61a9f1a9f19ca19ca19ca1bb61bb61bb61bb61bb61bb61bb61bb61bb61bb61bb61bb61bb61bb61bb61bb61bb61bb61bb61bb61bb61bb61bb619ca1bb61bb6";
hex"19db19db19db1ab01bc71bc71bc71ab01ab019db19db19db1bc71bc71bc71bc71bc71bc71bc71bc71bc71bc71bc71bc71bc71bc71bc71bc71bc71bc71bc71bc71bc71bc71bc71bc71bc719db1bc71bc7";

/// @dev Every two bytes is a function pointer for a literal parser.
/// Literal dispatches are determined by the first byte(s) of the literal
/// rather than a full word lookup, and are done with simple conditional
/// jumps as the possibilities are limited compared to the number of words we
/// have.
bytes constant LITERAL_PARSER_FUNCTION_POINTERS = hex"1512174417871825";
bytes constant LITERAL_PARSER_FUNCTION_POINTERS = hex"1523175517981836";
34 changes: 17 additions & 17 deletions src/lib/op/LibAllStandardOps.sol
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ import {LibOpUint256ERC20TotalSupply} from "./erc20/uint256/LibOpUint256ERC20Tot

import {LibOpERC20Allowance} from "./erc20/LibOpERC20Allowance.sol";
import {LibOpERC20BalanceOf} from "./erc20/LibOpERC20BalanceOf.sol";
// import {LibOpERC20TotalSupply} from "./erc20/LibOpERC20TotalSupply.sol";
import {LibOpERC20TotalSupply} from "./erc20/LibOpERC20TotalSupply.sol";

import {LibOpUint256ERC721BalanceOf} from "./erc721/uint256/LibOpUint256ERC721BalanceOf.sol";
import {LibOpERC721OwnerOf} from "./erc721/LibOpERC721OwnerOf.sol";
Expand Down Expand Up @@ -105,7 +105,7 @@ import {LibParseLiteralHex} from "../parse/literal/LibParseLiteralHex.sol";
import {LibParseLiteralSubParseable} from "../parse/literal/LibParseLiteralSubParseable.sol";

/// @dev Number of ops currently provided by `AllStandardOps`.
uint256 constant ALL_STANDARD_OPS_LENGTH = 38;
uint256 constant ALL_STANDARD_OPS_LENGTH = 40;

/// @title LibAllStandardOps
/// @notice Every opcode available from the core repository laid out as a single
Expand Down Expand Up @@ -168,10 +168,10 @@ library LibAllStandardOps {
"uint256-erc20-balance-of",
"Gets the balance of an erc20 token for an account as a uint256 value. The first input is the token address and the second is the account address."
),
// AuthoringMetaV2(
// "uint256-erc20-total-supply",
// "Gets the total supply of an erc20 token as a uint256 value. The input is the token address."
// ),
AuthoringMetaV2(
"uint256-erc20-total-supply",
"Gets the total supply of an erc20 token as a uint256 value. The input is the token address."
),
AuthoringMetaV2(
"erc20-allowance",
"Gets the allowance of an erc20 token for an account. The first input is the token address, the second is the owner address, and the third is the spender address. Lossy conversion to float so that \"infinite approve\" doesn't error."
Expand All @@ -180,9 +180,9 @@ library LibAllStandardOps {
"erc20-balance-of",
"Gets the balance of an erc20 token for an account. The first input is the token address and the second is the account address."
),
// AuthoringMetaV2(
// "erc20-total-supply", "Gets the total supply of an erc20 token. The input is the token address."
// ),
AuthoringMetaV2(
"erc20-total-supply", "Gets the total supply of an erc20 token. The input is the token address."
),
// AuthoringMetaV2(
// "uint256-erc721-balance-of",
// "Gets the balance of an erc721 token for an account as a uint256 value. The first input is the token address and the second is the account address."
Expand Down Expand Up @@ -389,14 +389,14 @@ library LibAllStandardOps {
LibParseOperand.handleOperandDisallowed,
// uint256-erc20-balance-of
LibParseOperand.handleOperandDisallowed,
// // uint256-erc20-total-supply
// LibParseOperand.handleOperandDisallowed,
// uint256-erc20-total-supply
LibParseOperand.handleOperandDisallowed,
// erc20-allowance
LibParseOperand.handleOperandDisallowed,
// erc20-balance-of
LibParseOperand.handleOperandDisallowed,
// // erc20-total-supply
// LibParseOperand.handleOperandDisallowed,
// erc20-total-supply
LibParseOperand.handleOperandDisallowed,
// // uint256-erc721-balance-of
// LibParseOperand.handleOperandDisallowed,
// erc721-owner-of
Expand Down Expand Up @@ -556,10 +556,10 @@ library LibAllStandardOps {
LibOpHashNP.integrity,
LibOpUint256ERC20Allowance.integrity,
LibOpUint256ERC20BalanceOf.integrity,
// LibOpUint256ERC20TotalSupply.integrity,
LibOpUint256ERC20TotalSupply.integrity,
LibOpERC20Allowance.integrity,
LibOpERC20BalanceOf.integrity,
// LibOpERC20TotalSupply.integrity,
LibOpERC20TotalSupply.integrity,
// LibOpUint256ERC721BalanceOf.integrity,
LibOpERC721OwnerOf.integrity,
LibOpERC5313OwnerNP.integrity,
Expand Down Expand Up @@ -668,10 +668,10 @@ library LibAllStandardOps {
LibOpHashNP.run,
LibOpUint256ERC20Allowance.run,
LibOpUint256ERC20BalanceOf.run,
// LibOpUint256ERC20TotalSupply.run,
LibOpUint256ERC20TotalSupply.run,
LibOpERC20Allowance.run,
LibOpERC20BalanceOf.run,
// LibOpERC20TotalSupply.run,
LibOpERC20TotalSupply.run,
// LibOpUint256ERC721BalanceOf.run,
LibOpERC721OwnerOf.run,
LibOpERC5313OwnerNP.run,
Expand Down
112 changes: 52 additions & 60 deletions src/lib/op/erc20/LibOpERC20TotalSupply.sol
Original file line number Diff line number Diff line change
@@ -1,63 +1,55 @@
// SPDX-License-Identifier: CAL
pragma solidity ^0.8.25;

// import {IERC20} from "openzeppelin-contracts/contracts/interfaces/IERC20.sol";
// import {Pointer} from "rain.solmem/lib/LibPointer.sol";
// import {IntegrityCheckState} from "../../integrity/LibIntegrityCheck.sol";
// import {OperandV2} from "rain.interpreter.interface/interface/unstable/IInterpreterV4.sol";
// import {InterpreterState} from "../../state/LibInterpreterState.sol";
// import {IERC20Metadata} from "openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Metadata.sol";

// /// @title LibOpERC20TotalSupply
// /// @notice Opcode for ERC20 `totalSupply`.
// library LibOpERC20TotalSupply {
// function integrity(IntegrityCheckState memory, Operand) internal pure returns (uint256, uint256) {
// // Always 1 input, the contract.
// // Always 1 output, the total supply.
// return (1, 1);
// }

// function run(InterpreterState memory, Operand, Pointer stackTop) internal view returns (Pointer) {
// uint256 token;
// assembly ("memory-safe") {
// token := mload(stackTop)
// }
// uint256 totalSupply = IERC20(address(uint160(token))).totalSupply();

// uint256 tokenDecimals = IERC20Metadata(address(uint160(token))).decimals();
// totalSupply = LibFixedPointDecimalScale.scale18(
// totalSupply,
// tokenDecimals,
// // Error on overflow as total supply is a critical value.
// // Rounding down is the default.
// 0
// );

// assembly ("memory-safe") {
// mstore(stackTop, totalSupply)
// }
// return stackTop;
// }

// function referenceFn(InterpreterState memory, Operand, uint256[] memory inputs)
// internal
// view
// returns (uint256[] memory)
// {
// uint256 account = inputs[0];
// uint256 totalSupply = IERC20(address(uint160(account))).totalSupply();

// uint256 tokenDecimals = IERC20Metadata(address(uint160(account))).decimals();
// totalSupply = LibFixedPointDecimalScale.scale18(
// totalSupply,
// tokenDecimals,
// // Error on overflow as total supply is a critical value.
// // Rounding down is the default.
// 0
// );

// uint256[] memory outputs = new uint256[](1);
// outputs[0] = totalSupply;
// return outputs;
// }
// }
import {IERC20} from "openzeppelin-contracts/contracts/interfaces/IERC20.sol";
import {Pointer} from "rain.solmem/lib/LibPointer.sol";
import {IntegrityCheckState} from "../../integrity/LibIntegrityCheck.sol";
import {OperandV2} from "rain.interpreter.interface/interface/unstable/IInterpreterV4.sol";
import {InterpreterState} from "../../state/LibInterpreterState.sol";
import {IERC20Metadata} from "openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Metadata.sol";
import {LibDecimalFloat, Float} from "rain.math.float/lib/LibDecimalFloat.sol";
import {StackItem} from "rain.interpreter.interface/interface/unstable/IInterpreterV4.sol";

/// @title LibOpERC20TotalSupply
/// @notice Opcode for ERC20 `totalSupply`.
library LibOpERC20TotalSupply {
function integrity(IntegrityCheckState memory, OperandV2) internal pure returns (uint256, uint256) {
// Always 1 input, the contract.
// Always 1 output, the total supply.
return (1, 1);
}

function run(InterpreterState memory, OperandV2, Pointer stackTop) internal view returns (Pointer) {
uint256 token;
assembly ("memory-safe") {
token := mload(stackTop)
}
uint256 totalSupply = IERC20(address(uint160(token))).totalSupply();

// This can fail as `decimals` is an OPTIONAL part of the ERC20 standard.
uint8 tokenDecimals = IERC20Metadata(address(uint160(token))).decimals();

Float totalSupplyFloat = LibDecimalFloat.fromFixedDecimalLosslessPacked(totalSupply, tokenDecimals);

assembly ("memory-safe") {
mstore(stackTop, totalSupplyFloat)
}
return stackTop;
}

function referenceFn(InterpreterState memory, OperandV2, StackItem[] memory inputs)
internal
view
returns (StackItem[] memory)
{
address account = address(uint160(uint256(StackItem.unwrap(inputs[0]))));
uint256 totalSupply = IERC20(account).totalSupply();

uint8 tokenDecimals = IERC20Metadata(address(uint160(account))).decimals();
Float totalSupplyFloat = LibDecimalFloat.fromFixedDecimalLosslessPacked(totalSupply, tokenDecimals);

StackItem[] memory outputs = new StackItem[](1);
outputs[0] = StackItem.wrap(Float.unwrap(totalSupplyFloat));
return outputs;
}
Comment on lines +40 to +54

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick (assertive)

Remove redundant address casting.

The variable account is already an address type, so the casting on line 48 is unnecessary.

-        uint8 tokenDecimals = IERC20Metadata(address(uint160(account))).decimals();
+        uint8 tokenDecimals = IERC20Metadata(account).decimals();
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
function referenceFn(InterpreterState memory, OperandV2, StackItem[] memory inputs)
internal
view
returns (StackItem[] memory)
{
address account = address(uint160(uint256(StackItem.unwrap(inputs[0]))));
uint256 totalSupply = IERC20(account).totalSupply();
uint8 tokenDecimals = IERC20Metadata(address(uint160(account))).decimals();
Float totalSupplyFloat = LibDecimalFloat.fromFixedDecimalLosslessPacked(totalSupply, tokenDecimals);
StackItem[] memory outputs = new StackItem[](1);
outputs[0] = StackItem.wrap(Float.unwrap(totalSupplyFloat));
return outputs;
}
function referenceFn(InterpreterState memory, OperandV2, StackItem[] memory inputs)
internal
view
returns (StackItem[] memory)
{
address account = address(uint160(uint256(StackItem.unwrap(inputs[0]))));
uint256 totalSupply = IERC20(account).totalSupply();
uint8 tokenDecimals = IERC20Metadata(account).decimals();
Float totalSupplyFloat = LibDecimalFloat.fromFixedDecimalLosslessPacked(totalSupply, tokenDecimals);
StackItem[] memory outputs = new StackItem[](1);
outputs[0] = StackItem.wrap(Float.unwrap(totalSupplyFloat));
return outputs;
}
🤖 Prompt for AI Agents
In src/lib/op/erc20/LibOpERC20TotalSupply.sol between lines 40 and 54, the
variable `account` is assigned by casting the input to an address with redundant
nested casts. Simplify this by removing the unnecessary inner cast to uint160
and directly cast the unwrapped input to address. This will clean up the code
without changing functionality.

}
13 changes: 7 additions & 6 deletions src/lib/op/erc20/uint256/LibOpUint256ERC20TotalSupply.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {Pointer} from "rain.solmem/lib/LibPointer.sol";
import {IntegrityCheckState} from "../../../integrity/LibIntegrityCheck.sol";
import {OperandV2} from "rain.interpreter.interface/interface/unstable/IInterpreterV4.sol";
import {InterpreterState} from "../../../state/LibInterpreterState.sol";
import {StackItem} from "rain.interpreter.interface/interface/unstable/IInterpreterV4.sol";

/// @title LibOpUint256ERC20TotalSupply
/// @notice Opcode for ERC20 `totalSupply`.
Expand All @@ -28,15 +29,15 @@ library LibOpUint256ERC20TotalSupply {
return stackTop;
}

function referenceFn(InterpreterState memory, OperandV2, uint256[] memory inputs)
function referenceFn(InterpreterState memory, OperandV2, StackItem[] memory inputs)
internal
view
returns (uint256[] memory)
returns (StackItem[] memory)
{
uint256 account = inputs[0];
uint256 totalSupply = IERC20(address(uint160(account))).totalSupply();
uint256[] memory outputs = new uint256[](1);
outputs[0] = totalSupply;
address account = address(uint160(uint256(StackItem.unwrap(inputs[0]))));
uint256 totalSupply = IERC20(account).totalSupply();
StackItem[] memory outputs = new StackItem[](1);
outputs[0] = StackItem.wrap(bytes32(totalSupply));
return outputs;
}
}
Loading
Loading