Skip to content

Commit

Permalink
wip on i9r bump
Browse files Browse the repository at this point in the history
  • Loading branch information
thedavidmeister committed Feb 28, 2024
1 parent cf1f7f8 commit 0a36669
Show file tree
Hide file tree
Showing 12 changed files with 1,244 additions and 0 deletions.
103 changes: 103 additions & 0 deletions src/interface/deprecated/v3/IFlowERC1155V3.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
// SPDX-License-Identifier: CAL
pragma solidity ^0.8.18;

import {SignedContextV1} from "rain.interpreter.interface/interface/IInterpreterCallerV2.sol";

import "./IFlowV3.sol";

/// @dev Entrypont of the `handleTransfer` evaluation.
SourceIndex constant FLOW_ERC1155_HANDLE_TRANSFER_ENTRYPOINT = SourceIndex.wrap(0);

/// @dev Minimum number of outputs of the `handleTransfer` evaluation.
/// This is 0 because the return stack is ignored.
uint256 constant FLOW_ERC1155_HANDLE_TRANSFER_MIN_OUTPUTS = 0;

/// @dev Maximum number of outputs of the `handleTransfer` evaluation.
/// This is 0 because the return stack is ignored.
uint16 constant FLOW_ERC1155_HANDLE_TRANSFER_MAX_OUTPUTS = 0;

/// @dev Minimum number of sentinels required by `FlowERC1155`.
/// This is 2 more than the minimum required by `FlowCommon` because the
/// mints and burns are included in the stack.
uint256 constant FLOW_ERC1155_MIN_FLOW_SENTINELS = MIN_FLOW_SENTINELS + 2;

/// @dev v3 of `FlowERC1155` expected a sentinel different to
/// `RAIN_FLOW_SENTINEL`, but this was generally more confusing than helpful.
Sentinel constant RAIN_FLOW_ERC1155_SENTINEL =
Sentinel.wrap(uint256(keccak256(bytes("RAIN_FLOW_ERC1155_SENTINEL")) | SENTINEL_HIGH_BITS));

/// Initializer config.
/// @param uri As per Open Zeppelin `ERC1155Upgradeable`.
/// @param evaluableConfig The `EvaluableConfigV2` to use to build the
/// `evaluable` that can be used to handle transfers.
/// @param flowConfig Constructor config for the `Evaluable`s that define the
/// flow behaviours including self mints/burns.
struct FlowERC1155Config {
string uri;
EvaluableConfig evaluableConfig;
EvaluableConfig[] flowConfig;
}

/// Represents a single mint or burn of a single ERC1155 token. Whether this is
/// a mint or burn must be implied by the context.
/// @param account The address the token is being minted/burned to/from.
/// @param id The id of the token being minted/burned.
/// @param amount The amount of the token being minted/burned.
struct ERC1155SupplyChange {
address account;
uint256 id;
uint256 amount;
}

/// Represents a set of ERC1155 transfers, including self mints/burns.
/// @param mints The mints that occurred.
/// @param burns The burns that occurred.
/// @param flow The transfers that occured.
struct FlowERC1155IOV1 {
ERC1155SupplyChange[] mints;
ERC1155SupplyChange[] burns;
FlowTransferV1 flow;
}

/// @title IFlowERC1155V3
/// Conceptually identical to `IFlowV3`, but the flow contract itself is an
/// ERC1155 token. This means that ERC1155 self mints and burns are included in
/// the stack that the flows must evaluate to. As stacks are processed by flow
/// from bottom to top, this means that the self mint/burn will be the last thing
/// evaluated, with mints at the bottom and burns next, followed by the flows.
///
/// As the flow is an ERC1155 token it also includes an evaluation to be run on
/// every token transfer. This is the `handleTransfer` entrypoint. The return
/// stack of this evaluation is ignored, but reverts MUST be respected. This
/// allows expression authors to prevent transfers from occurring if they don't
/// want them to, by reverting within the expression.
///
/// Otherwise the flow contract is identical to `IFlowV3`.
interface IFlowERC1155V3 {
/// Contract has initialized.
event Initialize(address sender, FlowERC1155Config config);

/// As per `IFlowV3` but returns a `FlowERC1155IOV1` instead of a
/// `FlowTransferV1`.
/// @param evaluable The `Evaluable` that is flowing.
/// @param callerContext The context of the caller.
/// @param signedContexts The signed contexts of the caller.
/// @return flowERC1155IO The `FlowERC1155IOV1` that occurred.
function previewFlow(
Evaluable calldata evaluable,
uint256[] calldata callerContext,
SignedContextV1[] calldata signedContexts
) external view returns (FlowERC1155IOV1 calldata flowERC1155IO);

/// As per `IFlowV3` but returns a `FlowERC1155IOV1` instead of a
/// `FlowTransferV1` and mints/burns itself as an ERC1155 accordingly.
/// @param evaluable The `Evaluable` that is flowing.
/// @param callerContext The context of the caller.
/// @param signedContexts The signed contexts of the caller.
/// @return flowERC1155IO The `FlowERC1155IOV1` that occurred.
function flow(
Evaluable calldata evaluable,
uint256[] calldata callerContext,
SignedContextV1[] calldata signedContexts
) external returns (FlowERC1155IOV1 calldata flowERC1155IO);
}
105 changes: 105 additions & 0 deletions src/interface/deprecated/v3/IFlowERC20V3.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
// SPDX-License-Identifier: CAL
pragma solidity ^0.8.18;

import "rain.interpreter.interface/interface/IInterpreterCallerV2.sol";
import "rain.interpreter.interface/lib/caller/LibEvaluable.sol";
import {Sentinel} from "rain.solmem/lib/LibStackSentinel.sol";
import {MIN_FLOW_SENTINELS, SENTINEL_HIGH_BITS, FlowTransferV1} from "./IFlowV3.sol";

/// @dev v3 of `FlowERC20` expected a sentinel different to
/// `RAIN_FLOW_SENTINEL`, but this was generally more confusing than helpful.
Sentinel constant RAIN_FLOW_ERC20_SENTINEL =
Sentinel.wrap(uint256(keccak256(bytes("RAIN_FLOW_ERC20_SENTINEL")) | SENTINEL_HIGH_BITS));

/// @dev Entrypont of the `handleTransfer` evaluation.
SourceIndex constant FLOW_ERC20_HANDLE_TRANSFER_ENTRYPOINT = SourceIndex.wrap(0);

/// @dev Minimum number of outputs of the `handleTransfer` evaluation.
/// This is 0 because the return stack is ignored.
uint256 constant FLOW_ERC20_HANDLE_TRANSFER_MIN_OUTPUTS = 0;

/// @dev Maximum number of outputs of the `handleTransfer` evaluation.
/// This is 0 because the return stack is ignored.
uint16 constant FLOW_ERC20_HANDLE_TRANSFER_MAX_OUTPUTS = 0;

/// @dev Minimum number of sentinels required by `FlowERC20`.
/// This is 2 more than the minimum required by `FlowCommon` because the
/// mints and burns are included in the stack.
uint256 constant FLOW_ERC20_MIN_FLOW_SENTINELS = MIN_FLOW_SENTINELS + 2;

/// Represents a single mint or burn of a single ERC20 token. Whether this is
/// a mint or burn must be implied by the context.
/// @param account The address the token is being minted/burned to/from.
/// @param amount The amount of the token being minted/burned.
struct ERC20SupplyChange {
address account;
uint256 amount;
}

/// Represents a set of ERC20 transfers, including self mints/burns.
/// @param mints The mints that occurred.
/// @param burns The burns that occurred.
/// @param flow The transfers that occured.
struct FlowERC20IOV1 {
ERC20SupplyChange[] mints;
ERC20SupplyChange[] burns;
FlowTransferV1 flow;
}

/// Initializer config.
/// @param name As per Open Zeppelin `ERC20Upgradeable`.
/// @param symbol As per Open Zeppelin `ERC20Upgradeable`.
/// @param evaluableConfig The `EvaluableConfigV2` to use to build the
/// `evaluable` that can be used to handle transfers.
/// @param flowConfig Initializer config for the `Evaluable`s that define the
/// flow behaviours including self mints/burns.
struct FlowERC20Config {
string name;
string symbol;
EvaluableConfig evaluableConfig;
EvaluableConfig[] flowConfig;
}

/// @title IFlowERC20V3
/// @notice Mints itself according to some predefined schedule. The schedule is
/// expressed as an expression and the `claim` function is world-callable.
/// Intended behaviour is to avoid sybils infinitely minting by putting the
/// claim functionality behind a `TierV2` contract. The flow contract
/// itself implements `ReadOnlyTier` and every time a claim is processed it
/// logs the block number of the claim against every tier claimed. So the block
/// numbers in the tier report for `FlowERC20` are the last time that tier
/// was claimed against this contract. The simplest way to make use of this
/// information is to take the max block for the underlying tier and the last
/// claim and then diff it against the current block number.
/// See `test/Claim/FlowERC20.sol.ts` for examples, including providing
/// staggered rewards where more tokens are minted for higher tier accounts.
interface IFlowERC20V3 {
/// Contract has initialized.
/// @param sender `msg.sender` initializing the contract (factory).
/// @param config All initialized config.
event Initialize(address sender, FlowERC20Config config);

/// As per `IFlowV3` but returns a `FlowERC20IOV1` instead of a
/// `FlowTransferV1`.
/// @param evaluable The `Evaluable` to use to evaluate the flow.
/// @param callerContext The caller context to use to evaluate the flow.
/// @param signedContexts The signed contexts to use to evaluate the flow.
/// @return flowERC20IO The `FlowERC20IOV1` that occurred.
function previewFlow(
Evaluable calldata evaluable,
uint256[] calldata callerContext,
SignedContextV1[] calldata signedContexts
) external view returns (FlowERC20IOV1 calldata flowERC20IO);

/// As per `IFlowV3` but returns a `FlowERC20IOV1` instead of a
/// `FlowTransferV1` and mints/burns itself as an ERC20 accordingly.
/// @param evaluable The `Evaluable` to use to evaluate the flow.
/// @param callerContext The caller context to use to evaluate the flow.
/// @param signedContexts The signed contexts to use to evaluate the flow.
/// @return flowERC20IO The `FlowERC20IOV1` that occurred.
function flow(
Evaluable calldata evaluable,
uint256[] calldata callerContext,
SignedContextV1[] calldata signedContexts
) external returns (FlowERC20IOV1 calldata flowERC20IO);
}
126 changes: 126 additions & 0 deletions src/interface/deprecated/v3/IFlowERC721V3.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
// SPDX-License-Identifier: CAL
pragma solidity ^0.8.18;

import "rain.interpreter.interface/interface/IInterpreterCallerV2.sol";
import "rain.interpreter.interface/lib/caller/LibEvaluable.sol";

import "./IFlowV3.sol";

/// @dev Entrypont of the `handleTransfer` evaluation.
SourceIndex constant FLOW_ERC721_HANDLE_TRANSFER_ENTRYPOINT = SourceIndex.wrap(0);
/// @dev Entrypont of the `tokenURI` evaluation.
SourceIndex constant FLOW_ERC721_TOKEN_URI_ENTRYPOINT = SourceIndex.wrap(1);

/// @dev Minimum number of outputs of the `handleTransfer` evaluation.
/// This is 0 because the return stack is ignored.
uint256 constant FLOW_ERC721_HANDLE_TRANSFER_MIN_OUTPUTS = 0;
/// @dev Minimum number of outputs of the `tokenURI` evaluation.
/// This is 1 because we can only handle a single token ID value.
uint256 constant FLOW_ERC721_TOKEN_URI_MIN_OUTPUTS = 1;

/// @dev Maximum number of outputs of the `handleTransfer` evaluation.
/// This is 0 because the return stack is ignored.
uint16 constant FLOW_ERC721_HANDLE_TRANSFER_MAX_OUTPUTS = 0;
/// @dev Maximum number of outputs of the `tokenURI` evaluation.
/// This is 1 because we can only handle a single token ID value.
uint16 constant FLOW_ERC721_TOKEN_URI_MAX_OUTPUTS = 1;

/// @dev v3 of `FlowERC721` expected a sentinel different to
/// `RAIN_FLOW_SENTINEL`, but this was generally more confusing than helpful.
Sentinel constant RAIN_FLOW_ERC721_SENTINEL =
Sentinel.wrap(uint256(keccak256(bytes("RAIN_FLOW_ERC721_SENTINEL")) | SENTINEL_HIGH_BITS));

/// @dev Minimum number of sentinels required by `FlowERC721`.
/// This is 2 more than the minimum required by `FlowCommon` because the
/// mints and burns are included in the stack.
uint256 constant FLOW_ERC721_MIN_FLOW_SENTINELS = MIN_FLOW_SENTINELS + 2;

/// Initializer config.
/// @param name As per Open Zeppelin `ERC721Upgradeable`.
/// @param symbol As per Open Zeppelin `ERC721Upgradeable`.
/// @param baseURI As per Open Zeppelin `ERC721Upgradeable`.
/// @param evaluableConfig The `EvaluableConfigV2` to use to build the
/// `evaluable` that can be used to handle transfers and token URIs. The token
/// URI entrypoint is optional.
/// @param flowConfig Constructor config for the `Evaluable`s that define the
/// flow behaviours including self mints/burns.
struct FlowERC721Config {
string name;
string symbol;
string baseURI;
EvaluableConfig evaluableConfig;
EvaluableConfig[] flowConfig;
}

/// Represents a single mint or burn of a single ERC721 token. Whether this is
/// a mint or burn must be implied by the context.
/// @param account The address the token is being minted/burned to/from.
/// @param id The id of the token being minted/burned.
struct ERC721SupplyChange {
address account;
uint256 id;
}

/// Represents a set of ERC721 transfers, including self mints/burns.
/// @param mints The mints that occurred.
/// @param burns The burns that occurred.
/// @param flow The transfers that occured.
struct FlowERC721IOV1 {
ERC721SupplyChange[] mints;
ERC721SupplyChange[] burns;
FlowTransferV1 flow;
}

/// @title IFlowERC721V3
/// Conceptually identical to `IFlowV3`, but the flow contract itself is an
/// ERC721 token. This means that ERC721 self mints and burns are included in
/// the stack.
///
/// As the flow is an ERC721 token, there are two entrypoints in addition to
/// the flows:
/// - `handleTransfer` is called when the flow is transferred.
/// - `tokenURI` is called when the token URI is requested.
///
/// The `handleTransfer` entrypoint is mandatory, but the `tokenURI` entrypoint
/// is optional. If the `tokenURI` entrypoint is not provided, the default
/// Open Zeppelin implementation will be used.
///
/// The `handleTransfer` entrypoint may be used to restrict transfers of the
/// flow token. For example, it may be used to restrict transfers to only
/// occur when the flow is in a certain state.
///
/// The `tokenURI` entrypoint may be used to provide a custom token ID to build
/// a token URI for the flow token.
///
/// Otherwise the flow contract behaves identically to `IFlowV3`.
interface IFlowERC721V3 {
/// Contract has initialized.
/// @param sender `msg.sender` initializing the contract (factory).
/// @param config All initialized config.
event Initialize(address sender, FlowERC721Config config);

/// As per `IFlowV3` but returns a `FlowERC721IOV1` instead of a
/// `FlowTransferV1`.
/// @param evaluable The `Evaluable` that is flowing.
/// @param callerContext The context of the caller.
/// @param signedContexts The signed contexts of the caller.
/// @return flowERC721IO The `FlowERC721IOV1` that would occur if the flow
/// was executed.
function previewFlow(
Evaluable calldata evaluable,
uint256[] calldata callerContext,
SignedContextV1[] calldata signedContexts
) external view returns (FlowERC721IOV1 calldata flowERC721IO);

/// As per `IFlowV3` but returns a `FlowERC721IOV1` instead of a
/// `FlowTransferV1` and mints/burns itself as an ERC721 accordingly.
/// @param evaluable The `Evaluable` that is flowing.
/// @param callerContext The context of the caller.
/// @param signedContexts The signed contexts of the caller.
/// @return flowERC721IO The `FlowERC721IOV1` that occurred.
function flow(
Evaluable calldata evaluable,
uint256[] calldata callerContext,
SignedContextV1[] calldata signedContexts
) external returns (FlowERC721IOV1 calldata flowERC721IO);
}
Loading

0 comments on commit 0a36669

Please sign in to comment.