You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Brendan Sanderson, Funderberker, Ben Weintraub, Brean, Guy
Summary
Tractor is a peer-to-peer transaction marketplace that allows third party operators to perform Beanstalk actions on behalf of a Farmer;
Blueprints are off-chain data structures that are EIP-712 signed to verify the intent of the publishing Farmer; and
Junctions are contracts that are contain functions that are used by Tractor orders.
Abstract
EVM users frequently demand peer-to-peer transactions. Existing peer-to-peer transaction marketplaces (such as Seaport) are limited in the scope of the functionality that they support. Existing generalized function call systems (smart contract accounts, Depot + Pipeline) only support the use of assets from the sender of the transaction. Tractor introduces a generalized function call peer-to-peer transaction marketplace.
Tractor
Blueprints allow Farmers to define sequences of on-chain function calls, which can be executed permissionlessly by other Farmers known as Tractor Operators.
Farmers Publish and Destroy Blueprints. Blueprints are EIP-712 signed payloads containing a Publisher, an Advanced Farm function call containing an arbitrary sequence of internal function calls, a set of copy instructions that define how to interpret operator calldata, expiry parameters and the EIP-712 signature from the Publisher. Any Tractor Operator can execute any Blueprint with any calldata at anytime through the tractor(...) function provided that the Blueprint does not revert.
Junctions allow Farmers to define Blueprints that will fail under a predefined set of conditions, such as balance limits, price thresholds, etc.
Examples
A Farmer creates a Blueprint for an Operator to Plant on their behalf anytime they have more than 100 Plantable Seeds and will pay the caller 1 Earned Bean.
A Farmer creates a Blueprint for an Operator to Rinse and Deposit on their behalf anytime they have more than 200 Rinsable Sprouts and will pay the caller 5 USDC.
A Farmer creates a Blueprint for an Operator to Convert their urBEANETH to urBEAN on their behalf anytime the Bean price is below $0.96 with no tip (the Operator just has to pay gas).
Rollout
Tractor is an on-chain primitive. Supporting markets on top of Tractor requires significant off-chain development in the form of indexers, middleware, and frontends. At the time of Tractor deployment, the goal is to first support Automated Farming, i.e., creating and executing orders for Mow and Plant with tips paid in ERC-20 tokens from the Publisher's Farm or Circulating balances.
Later the goal is to support a Convert order book on top of Tractor.
Specification
Blueprints
Blueprints are off-chain data structures that are EIP-712 signed to verify publisher intent. Each Blueprint contains an arbitrary sequence of internal and external function calls wrapped into an AdvancedFarm call and to be executed through the Tractor Facet. Any properly signed Blueprint can be executed through Tractor given:
startTime < block.timestamp < endTime;
blueprintNonce[nonce] < maxNonce; and
the advancedFarm function call does not revert (Publishers can encode logic checks that revert under arbitrary conditions)
publisher is the account that published the Blueprint;
data is bytes that decode into (AdvancedFarmCall[]);
operatorPasteInstrs are a set of instructions that define how operator-defiend data is injected into the AdvancedFarmCalls of the data;
maxNonce The maximum # of times a Blueprint can be executed;
startTime The timestamp at which the Blueprint can start to be executed;
endTime The timestamp at which the Blueprint can no longer be executed;
blueprintHash The keccak256 hash of the populated Blueprint struct; and
signature The Publisher's EIP-712 signature of the Blueprint Hash.
Blueprint Hash
Blueprint Hashes are unique identifiers for Blueprints. Blueprint Hashes are used to track the nonce of a Blueprint and used in the signing process. A Blueprint Hash must be hashed following the EIP-712 standard. Beanstalk providesa public helper function getBlueprintHash(Blueprint blueprint).
Publish Blueprint
Requisitions do not need to be written on-chain. They can be provided to operators off-chain and verified via the signature. However, Tractor offers a system to publicly publish any Requisition via the PublishRequisition function, which emits an event containing the Requisition.
function functionpublishRequisition(LibTractor.Requisition calldatarequisition) external;
event PublishRequisition(LibTractor.Requisition requisition);
Destroy Blueprint
Blueprints can be canceled at anytime by the Blueprint Publisher by calling cancelBlueprint. This sets the nonce to uint256.max, rendering the Blueprint unusable.
function cancelBlueprint(LibTractor.Requisition calldatarequisition) external;
event CancelBlueprint(bytes32blueprintHash);
Tractor
function tractor(LibTractor.Requisition calldatarequisition, bytesmemoryoperatorData) externalreturns (bytes[] memoryresults);
event Tractor(addressindexedoperator, bytes32blueprintHash);
Tractor executes a Blueprint. Executing a Blueprint does the following:
Verifies the Blueprint signature is correct;
Checks startTime < block.timestamp < endTime;
Checks blueprintNonce[blueprintHash] < maxNonce;
Increments blueprintNonce[blueprintHash];
Modifies blueprint.data using the operatorPasteInstrs and operatorData;
Executes advancedFarm using data; and
Emits a Tractor event.
Tractor Storage
Instead of adding new state variables to AppStorage, create a TractorStorage library where TractorStorage is loaded at slot keccak256("diamond.storage.tractor") (store as a constant).
Blueprints can utilize arbitrary counters to track and limit use. These are stored in TractorStorage and writes are restricted based on the Publisher's address. Blueprints using counters are expected to generate sufficiently random counter IDs to avoid collisions with a Publisher's other counters.
Active Publisher
Tractor performs actions on behalf of the Publisher of a Blueprint that that is executed by Tractor. Rather than using msg.sender to determine the account to act on, the active Publisher address is used.
Junctions
TBD.
The text was updated successfully, but these errors were encountered:
RFC: Tractor
Authors
Brendan Sanderson, Funderberker, Ben Weintraub, Brean, Guy
Summary
Abstract
EVM users frequently demand peer-to-peer transactions. Existing peer-to-peer transaction marketplaces (such as Seaport) are limited in the scope of the functionality that they support. Existing generalized function call systems (smart contract accounts, Depot + Pipeline) only support the use of assets from the sender of the transaction. Tractor introduces a generalized function call peer-to-peer transaction marketplace.
Tractor
Blueprints allow Farmers to define sequences of on-chain function calls, which can be executed permissionlessly by other Farmers known as Tractor Operators.
Farmers Publish and Destroy Blueprints. Blueprints are EIP-712 signed payloads containing a Publisher, an Advanced Farm function call containing an arbitrary sequence of internal function calls, a set of copy instructions that define how to interpret operator calldata, expiry parameters and the EIP-712 signature from the Publisher. Any Tractor Operator can execute any Blueprint with any calldata at anytime through the
tractor(...)
function provided that the Blueprint does not revert.Junctions allow Farmers to define Blueprints that will fail under a predefined set of conditions, such as balance limits, price thresholds, etc.
Examples
A Farmer creates a Blueprint for an Operator to Plant on their behalf anytime they have more than 100 Plantable Seeds and will pay the caller 1 Earned Bean.
A Farmer creates a Blueprint for an Operator to Rinse and Deposit on their behalf anytime they have more than 200 Rinsable Sprouts and will pay the caller 5 USDC.
A Farmer creates a Blueprint for an Operator to Convert their urBEANETH to urBEAN on their behalf anytime the Bean price is below $0.96 with no tip (the Operator just has to pay gas).
Rollout
Tractor is an on-chain primitive. Supporting markets on top of Tractor requires significant off-chain development in the form of indexers, middleware, and frontends. At the time of Tractor deployment, the goal is to first support Automated Farming, i.e., creating and executing orders for Mow and Plant with tips paid in ERC-20 tokens from the Publisher's Farm or Circulating balances.
Later the goal is to support a Convert order book on top of Tractor.
Specification
Blueprints
Blueprints are off-chain data structures that are EIP-712 signed to verify publisher intent. Each Blueprint contains an arbitrary sequence of internal and external function calls wrapped into an AdvancedFarm call and to be executed through the Tractor Facet. Any properly signed Blueprint can be executed through Tractor given:
startTime < block.timestamp < endTime
;blueprintNonce[nonce] < maxNonce
; andadvancedFarm
function call does not revert (Publishers can encode logic checks that revert under arbitrary conditions)Blueprints are defined by the following struct:
Blueprints are wrapped in a Requisition, which contains the Blueprint hash and the Publisher's signature of the hash.
Where:
publisher
is the account that published the Blueprint;data
is bytes that decode into(AdvancedFarmCall[])
;operatorPasteInstrs
are a set of instructions that define how operator-defiend data is injected into the AdvancedFarmCalls of thedata
;maxNonce
The maximum # of times a Blueprint can be executed;startTime
The timestamp at which the Blueprint can start to be executed;endTime
The timestamp at which the Blueprint can no longer be executed;blueprintHash
The keccak256 hash of the populated Blueprint struct; andsignature
The Publisher's EIP-712 signature of the Blueprint Hash.Blueprint Hash
Blueprint Hashes are unique identifiers for Blueprints. Blueprint Hashes are used to track the nonce of a Blueprint and used in the signing process. A Blueprint Hash must be hashed following the EIP-712 standard. Beanstalk providesa public helper function
getBlueprintHash(Blueprint blueprint)
.Publish Blueprint
Requisitions do not need to be written on-chain. They can be provided to operators off-chain and verified via the signature. However, Tractor offers a system to publicly publish any Requisition via the
PublishRequisition
function, which emits an event containing the Requisition.Destroy Blueprint
Blueprints can be canceled at anytime by the Blueprint Publisher by calling
cancelBlueprint
. This sets the nonce touint256.max
, rendering the Blueprint unusable.Tractor
Tractor executes a Blueprint. Executing a Blueprint does the following:
startTime < block.timestamp < endTime
;blueprintNonce[blueprintHash] < maxNonce
;blueprintNonce[blueprintHash]
;blueprint.data
using theoperatorPasteInstrs
andoperatorData
;advancedFarm
usingdata
; andTractor
event.Tractor Storage
Instead of adding new state variables to
AppStorage
, create aTractorStorage
library whereTractorStorage
is loaded at slotkeccak256("diamond.storage.tractor")
(store as a constant).Tractor Counters
Blueprints can utilize arbitrary counters to track and limit use. These are stored in TractorStorage and writes are restricted based on the Publisher's address. Blueprints using counters are expected to generate sufficiently random counter IDs to avoid collisions with a Publisher's other counters.
Active Publisher
Tractor performs actions on behalf of the Publisher of a Blueprint that that is executed by Tractor. Rather than using
msg.sender
to determine the account to act on, the active Publisher address is used.Junctions
TBD.
The text was updated successfully, but these errors were encountered: