-
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
cf1f7f8
commit 0a36669
Showing
12 changed files
with
1,244 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,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); | ||
} |
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,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); | ||
} |
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,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); | ||
} |
Oops, something went wrong.