From 933919158108b7f3d67eb5daac9d8acad299ce07 Mon Sep 17 00:00:00 2001 From: Margarita Skomorokh Date: Tue, 24 Dec 2024 15:03:35 +0100 Subject: [PATCH] partially edited the basic agent section --- .../_category_.json | 4 +- .../agent_factory.md | 56 ++-- .../deploy_script.md | 44 ++-- .../build-a-basic-warden-agent/deployment.md | 248 +++++++++--------- .../main_contract.md | 110 ++++---- .../build-a-basic-warden-agent/plan.md | 62 +---- .../build-a-basic-warden-agent/precompiles.md | 109 ++++---- .../prerequisites.md | 59 +++++ .../build-a-basic-warden-agent/structure.md | 90 ++++--- 9 files changed, 421 insertions(+), 361 deletions(-) create mode 100644 docs/developer-docs/docs/build-an-app/build-a-basic-warden-agent/prerequisites.md diff --git a/docs/developer-docs/docs/build-an-app/build-a-basic-warden-agent/_category_.json b/docs/developer-docs/docs/build-an-app/build-a-basic-warden-agent/_category_.json index f4074acda..8ed486051 100644 --- a/docs/developer-docs/docs/build-an-app/build-a-basic-warden-agent/_category_.json +++ b/docs/developer-docs/docs/build-an-app/build-a-basic-warden-agent/_category_.json @@ -1,11 +1,11 @@ { "position": 6, - "label": "Basic Warden Agent", + "label": "Build a Basic Warden Agent", "collapsible": true, "collapsed": false, "link": { "type": "generated-index", - "title": "Basic Warden Agent" + "title": "Build a Basic Warden Agent" }, "customProps": {} } \ No newline at end of file diff --git a/docs/developer-docs/docs/build-an-app/build-a-basic-warden-agent/agent_factory.md b/docs/developer-docs/docs/build-an-app/build-a-basic-warden-agent/agent_factory.md index a1f89431f..1d2e639de 100644 --- a/docs/developer-docs/docs/build-an-app/build-a-basic-warden-agent/agent_factory.md +++ b/docs/developer-docs/docs/build-an-app/build-a-basic-warden-agent/agent_factory.md @@ -1,16 +1,18 @@ --- -sidebar_position: 5 +sidebar_position: 6 --- -# Order Factory Contract +# Create the OrderFactory contract -## Implementing the Order Factory Contract +The `OrderFactory` contract manages agent creation and tracking with enhanced security features. -The OrderFactory contract manages agent creation and tracking with enhanced security features: +Create a contract `OrderFactory.sol`. -Create - `src/OrderFactory.sol`: +:::note GitHub +You can find the full code on GitHub: [`/src/OrderFactory.sol`](https://github.com/warden-protocol/wardenprotocol/blob/main/solidity/orders/src/OrderFactory.sol) +::: -```solidity +```solidity title="/src/OrderFactory.sol" contract OrderFactory is Ownable { // NEW: Enhanced tracking and security mapping(address orderAddress => address orderCreator) public orders; @@ -37,24 +39,24 @@ contract OrderFactory is Ownable { } ``` -[Code Reference](https://github.com/warden-protocol/wardenprotocol/blob/main/solidity/orders/src/OrderFactory.sol) - -**Key Features:** - -1.Factory Pattern: - -- Creates new order instances -- Tracks order creators -- Supports multiple order types - -2.Management: - -- Ownable for admin control -- Scheduler management -- Registry integration - -3.Order Creation: - -- Basic orders supported -- Advanced orders placeholder -- Order registration in Registry +**Key features:** + +1. Factory pattern: + + - Creates new order instances + - Tracks order creators + - Supports multiple order types + +2. Management: + + - Ownable for admin control + - Scheduler management + - Registry integration + +3. Order creation: + + - Basic orders supported + - Advanced orders placeholder + - Order registration in Registry + +After creating the Orderfactory contract, you can [implement the deployment scripts](deploy_script). diff --git a/docs/developer-docs/docs/build-an-app/build-a-basic-warden-agent/deploy_script.md b/docs/developer-docs/docs/build-an-app/build-a-basic-warden-agent/deploy_script.md index ccb385b70..91192c2d7 100644 --- a/docs/developer-docs/docs/build-an-app/build-a-basic-warden-agent/deploy_script.md +++ b/docs/developer-docs/docs/build-an-app/build-a-basic-warden-agent/deploy_script.md @@ -1,14 +1,20 @@ --- -sidebar_position: 6 +sidebar_position: 7 --- -# Deploy Script +# Implement the deployment scripts + +## Overview Let's implement the deployment scripts. We'll need two scripts: one for deployment and one for creating orders. -## Create `script/Deploy.s.sol:` +## 1. Implement a script for deployment + +:::note GitHub +You can find the full code on GitHub: [`/script/Deploy.s.sol`](https://github.com/warden-protocol/wardenprotocol/blob/main/solidity/orders/script/Deploy.s.sol) +::: -```solidity +```solidity title="/script/Deploy.s.sol" contract Deploy is Script { function run() external { vm.startBroadcast(broadcaster); @@ -29,11 +35,19 @@ contract Deploy is Script { } ``` -[Code Reference](https://github.com/warden-protocol/wardenprotocol/blob/main/solidity/orders/script/Deploy.s.sol) +This script handles the following tasks: + +1. Registry deployment +2. Factory deployment +3. Environment configuration + +## 2. Implement a script for creating orders -## Create `script/CreateOrder.s.sol:` +:::note GitHub +You can find the full code on GitHub: [`/script/CreateOrder.s.sol`](https://github.com/warden-protocol/wardenprotocol/blob/main/solidity/orders/script/CreateOrder.s.sol) +::: -```solidity +```solidity title="/script/CreateOrder.s.sol" contract CreateOrder is Script { function run( uint256 thresholdPrice, @@ -50,18 +64,12 @@ contract CreateOrder is Script { } ``` -[Code Reference](https://github.com/warden-protocol/wardenprotocol/blob/main/solidity/orders/script/CreateOrder.s.sol) - -### These scripts handle the following tasks - -**Deploy.s.sol:** - -1. Registry deployment -2. Factory deployment -3. Environment configuration - -**CreateOrder.s.sol:** +This script handles the following tasks: 1. Order creation through factory 2. Mock precompiles setup 3. Parameter configuration + +## Next steps + +After creating implementing the deployment scripts, you can finally [deploy the trading Agent](deployment). \ No newline at end of file diff --git a/docs/developer-docs/docs/build-an-app/build-a-basic-warden-agent/deployment.md b/docs/developer-docs/docs/build-an-app/build-a-basic-warden-agent/deployment.md index da89b7d4e..e6a0ee38f 100644 --- a/docs/developer-docs/docs/build-an-app/build-a-basic-warden-agent/deployment.md +++ b/docs/developer-docs/docs/build-an-app/build-a-basic-warden-agent/deployment.md @@ -2,126 +2,128 @@ sidebar_position: 7 --- -# Deploy Trading Agent - -## The following implementation will guide you through the process of how To Deploy & Test the Warden Agent - -### Deployment Steps - -1.Set up the environment file (.env) - -```bash -MNEMONIC="your mnemonic phrase here" -RPC_URL="http://127.0.0.1:8545" -CHAIN_ID="12345" -SCHEDULER_ADDRESS="0x6EA8AC1673402989E7B653AE4E83B54173719C30" -FACTORY_OWNER_ADDRESS="0x6EA8AC1673402989E7B653AE4E83B54173719C30" -``` - -2.Compile the contract: - -```bash -forge build -``` - -3.Deploy the Base Contract: - -```bash -# Load environment -source .env - -# Deploy Registry and Factory -forge script script/Deploy.s.sol:Deploy \ - --rpc-url $RPC_URL \ - --broadcast \ - --chain-id $CHAIN_ID -``` - -4.Create an order - -```bash -forge script script/CreateOrder.s.sol:CreateOrder \ - --rpc-url $RPC_URL \ - --broadcast \ - --sig "run(uint256,uint8,(string,string),(uint256,uint256,address),(uint256,address[],address,uint256),uint64,uint64,uint64,bytes,bytes)" \ - 3324181371 \ # threshold price - 0 \ # LTE condition - '("ETH","USD")' \ # price pair - '(100000000000000,11155111,0x467b...)' \ # tx fields - # ... other parameters -``` - -**Key Parameters Explained:** - -`thresholdPrice:` Price level to trigger execution -`priceCondition:` 0 for LTE, 1 for GTE -`pricePair:` Trading pair (e.g., "ETH/USD") -`creatorDefinedTxFields:` Chain and transaction details -`swapData:` Uniswap swap parameters -`keyId:` Warden signing key ID -`spaceNonce:` Nonce for the signing space -`actionTimeoutHeight:` Timeout for execution -`expectedApproveExpression:` Conditions for approval -`expectedRejectExpression:` Conditions for rejection - -5.Verify deployment: - -```bash -# Get order details -cast call $ORDER_ADDRESS "orderData()" -``` - -### Monitoring and Managing Orders - -1.Monitor order status: - -```bash -# Check if order can execute -cast call $ORDER_ADDRESS "canExecute()" --rpc-url $RPC_URL - -# Check if order has been executed -cast call $ORDER_ADDRESS "isExecuted()" --rpc-url $RPC_URL - -# Get execution data -cast call $ORDER_ADDRESS "executionData()" --rpc-url $RPC_URL -``` - -2.Track in Registry: - -```bash -# Get order creator from registry -cast call $REGISTRY_ADDRESS "executions(address)" $ORDER_ADDRESS - -# Get transaction details -cast call $REGISTRY_ADDRESS "transactions(bytes32)" $TX_HASH -``` - -3.Monitor events: - -```bash -# Watch for Executed events -cast logs $ORDER_ADDRESS "Executed()" - -# Watch for NewTx events in Registry -cast logs $REGISTRY_ADDRESS "NewTx(address,bytes32)" -``` - -4.Utility commands: - -```bash -# Get current price from Slinky -cast call $SLINKY_PRECOMPILE "getPrice(string,string)" "ETH" "USD" - -# Check Warden key status -cast call $WARDEN_PRECOMPILE "keyById(uint64,int32[])" $KEY_ID [] -``` - -5.Debug tools: - -```bash -# Get raw transaction data -cast call $ORDER_ADDRESS "getTx()" - -# Check callers list -cast call $ORDER_ADDRESS "callers()" -``` +# Deploy the trading Agent + +## Overview + +The following implementation will guide you through the process of how to deploy and test the basic Warden Agent. + +### 1. Deploy the Agent + +1. Set up the environment file (.env) + + ```bash + MNEMONIC="your mnemonic phrase here" + RPC_URL="http://127.0.0.1:8545" + CHAIN_ID="12345" + SCHEDULER_ADDRESS="0x6EA8AC1673402989E7B653AE4E83B54173719C30" + FACTORY_OWNER_ADDRESS="0x6EA8AC1673402989E7B653AE4E83B54173719C30" + ``` + +2. Compile the contract: + + ```bash + forge build + ``` + +3. Deploy the Base Contract: + + ```bash + # Load environment + source .env + + # Deploy Registry and Factory + forge script script/Deploy.s.sol:Deploy \ + --rpc-url $RPC_URL \ + --broadcast \ + --chain-id $CHAIN_ID + ``` + +4. Create an order + + ```bash + forge script script/CreateOrder.s.sol:CreateOrder \ + --rpc-url $RPC_URL \ + --broadcast \ + --sig "run(uint256,uint8,(string,string),(uint256,uint256,address),(uint256,address[],address,uint256),uint64,uint64, uint64,bytes,bytes)" \ + 3324181371 \ # threshold price + 0 \ # LTE condition + '("ETH","USD")' \ # price pair + '(100000000000000,11155111,0x467b...)' \ # tx fields + # ... other parameters + ``` + + **Key parameters explained:** + + - `thresholdPrice`: Price level to trigger execution + - `priceCondition`: 0 for LTE, 1 for GTE + - `pricePair`: Trading pair (e.g., "ETH/USD") + - `creatorDefinedTxFields`: Chain and transaction details + - `swapData`: Uniswap swap parameters + - `keyId`: Warden signing key ID + - `spaceNonce`: Nonce for the signing space + - `actionTimeoutHeight`: Timeout for execution + - `expectedApproveExpression`: Conditions for approval + - `expectedRejectExpression`: Conditions for rejection + +5. Verify the deployment: + + ```bash + # Get order details + cast call $ORDER_ADDRESS "orderData()" + ``` + +### 2. Monitor and manage orders + +1. Monitor order status: + + ```bash + # Check if order can execute + cast call $ORDER_ADDRESS "canExecute()" --rpc-url $RPC_URL + + # Check if order has been executed + cast call $ORDER_ADDRESS "isExecuted()" --rpc-url $RPC_URL + + # Get execution data + cast call $ORDER_ADDRESS "executionData()" --rpc-url $RPC_URL + ``` + +2. Track in Registry: + + ```bash + # Get order creator from registry + cast call $REGISTRY_ADDRESS "executions(address)" $ORDER_ADDRESS + + # Get transaction details + cast call $REGISTRY_ADDRESS "transactions(bytes32)" $TX_HASH + ``` + +3. Monitor events: + + ```bash + # Watch for Executed events + cast logs $ORDER_ADDRESS "Executed()" + + # Watch for NewTx events in Registry + cast logs $REGISTRY_ADDRESS "NewTx(address,bytes32)" + ``` + +4. Utility commands: + + ```bash + # Get current price from Slinky + cast call $SLINKY_PRECOMPILE "getPrice(string,string)" "ETH" "USD" + + # Check Warden key status + cast call $WARDEN_PRECOMPILE "keyById(uint64,int32[])" $KEY_ID [] + ``` + +5. Debug tools: + + ```bash + # Get raw transaction data + cast call $ORDER_ADDRESS "getTx()" + + # Check callers list + cast call $ORDER_ADDRESS "callers()" + ``` diff --git a/docs/developer-docs/docs/build-an-app/build-a-basic-warden-agent/main_contract.md b/docs/developer-docs/docs/build-an-app/build-a-basic-warden-agent/main_contract.md index ca8fbccda..d51cff6ad 100644 --- a/docs/developer-docs/docs/build-an-app/build-a-basic-warden-agent/main_contract.md +++ b/docs/developer-docs/docs/build-an-app/build-a-basic-warden-agent/main_contract.md @@ -1,18 +1,24 @@ --- -sidebar_position: 4 +sidebar_position: 5 --- -# Trading Agent Implementation +# Create the trading Agent + +## Overview Let's create our main trading agent that implements the automated Uniswap trading logic. -## BasicOrder Contract (`src/BasicOrder.sol`) +Create the `BasicOrder` contract + +:::note GitHub +You can find the full code on GitHub: [`/src/BasicOrder.sol`](https://github.com/warden-protocol/wardenprotocol/blob/main/solidity/orders/src/BasicOrder.sol) +::: -### Core Components +## 1. Create the core components First, let's define our state variables and imports: -```solidity +```solidity title="/src/BasicOrder.sol" contract BasicOrder is IExecution, ReentrancyGuard { // NEW: Constant for Uniswap interface string public constant SWAP_EXACT_ETH_FOR_TOKENS = @@ -31,9 +37,9 @@ contract BasicOrder is IExecution, ReentrancyGuard { } ``` -### Constructor with Validations +## 2. Create a constructor with validations -```solidity +```solidity title="/src/BasicOrder.sol" constructor( Types.OrderData memory _orderData, CommonTypes.Coin[] memory maxKeychainFees, @@ -53,9 +59,9 @@ constructor( } ``` -### Price Monitoring Logic +## 3. Create the price monitoring logic -```solidity +```solidity title="/src/BasicOrder.sol" function canExecute() public view returns (bool value) { // NEW: Enhanced price condition checking GetPriceResponse memory priceResponse = @@ -72,9 +78,9 @@ function canExecute() public view returns (bool value) { } ``` -### Trade Execution +## 4. Implement the trade execution -```solidity +```solidity title="/src/BasicOrder.sol" function execute( uint256 nonce, uint256 gas, @@ -103,8 +109,6 @@ function execute( } ``` -[Code Reference](https://github.com/warden-protocol/wardenprotocol/blob/main/solidity/orders/src/BasicOrder.sol) - ## Flow 1.Construction: @@ -113,11 +117,11 @@ function execute( - Sets up price feed and signing service connections - Initializes order parameters -2.Price Monitoring (`canExecute`): +2.Price monitoring (`canExecute`): - Check if price meets conditions. -3.Trade Execution (`execute`): +3.Trade execution (`execute`): a. Verify caller and conditions b. Pack swap data for Uniswap @@ -126,14 +130,14 @@ d. Request signature through Warden e. Register transaction in Registry f. Return execution status -## Key Security Features +## Key security features -1.**ReentrancyGuard Protection** +1.**ReentrancyGuard protection** - Prevents reentrancy attacks during execution - Guards critical state changes -2.**Input Validation** +2.**Input validation** ```solidity // Example of comprehensive validation @@ -141,13 +145,13 @@ if (_orderData.thresholdPrice == 0) revert InvalidThresholdPrice(); if (_orderData.creatorDefinedTxFields.to == address(0)) revert InvalidTxTo(); ``` -3.**Transaction Safety** +3.**Transaction safety** - EIP-1559 transaction support - Secure RLP encoding - Transaction hash verification -## Monitoring and Events +## Monitoring and events ```solidity event Executed(); @@ -155,34 +159,38 @@ event PriceConditionMet(uint256 currentPrice, uint256 thresholdPrice); event TransactionRegistered(bytes32 indexed txHash); ``` -## Testing Considerations - -1.**Test price conditions** - -```solidity -function test_priceConditions() public { - // Test GTE condition - vm.mockCall( - address(SLINKY_PRECOMPILE), - abi.encodeWithSelector(ISlinky.getPrice.selector), - abi.encode(price) - ); - assertTrue(order.canExecute()); -} -``` - -2.**Test Execution Flow** - -```solidity -function test_execution() public { - vm.startPrank(scheduler); - (bool success, bytes32 txHash) = order.execute( - 1, // nonce - 200000, // gas - 0, // unused - 2 gwei, // maxPriorityFeePerGas - 100 gwei // maxFeePerGas - ); - assertTrue(success); -} -``` +## Testing considerations + +1. **Test price conditions** + + ```solidity + function test_priceConditions() public { + // Test GTE condition + vm.mockCall( + address(SLINKY_PRECOMPILE), + abi.encodeWithSelector(ISlinky.getPrice.selector), + abi.encode(price) + ); + assertTrue(order.canExecute()); + } + ``` + +2. **Test the execution flow** + + ```solidity + function test_execution() public { + vm.startPrank(scheduler); + (bool success, bytes32 txHash) = order.execute( + 1, // nonce + 200000, // gas + 0, // unused + 2 gwei, // maxPriorityFeePerGas + 100 gwei // maxFeePerGas + ); + assertTrue(success); + } + ``` + +## Next steps + +After creating the trading Agent, you can [create the OrderFactory contract](agent_factory). diff --git a/docs/developer-docs/docs/build-an-app/build-a-basic-warden-agent/plan.md b/docs/developer-docs/docs/build-an-app/build-a-basic-warden-agent/plan.md index f37428c2e..eb7f0fdcc 100644 --- a/docs/developer-docs/docs/build-an-app/build-a-basic-warden-agent/plan.md +++ b/docs/developer-docs/docs/build-an-app/build-a-basic-warden-agent/plan.md @@ -2,11 +2,11 @@ sidebar_position: 1 --- -# Build a Basic Warden Agent +# Introduction -## Overview +## Basic Warden Agent -This tutorial will guide you through the process of building a basic **Warden Agent.** In this basic version of the tutorial, we'll focus on automated token trading based on price conditions. It will allow you to create orders that automatically execute token swaps on Uniswap when certain price thresholds are met. +This tutorial will guide you through the process of building a **Basic Warden Agent.** In this basic version of the tutorial, we'll focus on automated token trading based on price conditions. It will allow you to create orders that automatically execute token swaps on Uniswap when certain price thresholds are met. In the more advanced tutorial you will learn how to build a **Warden Agent** that executes orders based on AI predictions. @@ -50,59 +50,3 @@ You can find the full sample code on [GitHub](https://github.com/warden-protocol 5. Transaction details are stored in Registry for verification/tracking 6. Deploy and create agent instances 7. Monitor and manage agents - -## Prerequisites - -### You are expected to posses the following knowledge - -- Solidity (especially inheritance, interfaces, events) -- Basic understanding of Uniswap V2 -- Familiarity with price oracles -- Understanding of RLP encoding for transactions - -### Environment Setup - -1.Install required dependencies: - -```bash -forge install OpenZeppelin/openzeppelin-contracts -forge install Uniswap/v2-periphery -``` - -2.Configure foundry.toml: - -```bash -[profile.default] -auto_detect_solc = false -block_timestamp = 1_680_220_800 -bytecode_hash = "none" -evm_version = "paris" -fuzz = { runs = 1_000 } -gas_reports = ["*"] -optimizer = true -optimizer_runs = 10_000 -solc = "0.8.25" - -[fmt] -bracket_spacing = true -int_types = "long" -line_length = 120 -multiline_func_header = "all" -number_underscore = "thousands" -quote_style = "double" -tab_width = 4 -wrap_comments = true -``` - -### Directory Structure - -```bash - uniswap-trading-agent -warden-trading-agent/ -├── src/ # Core contracts -├── scripts/ # Deployment scripts -├── test/ # Test files -└── mocks/ # Mock services -``` - -In the next chapter you will learn how to implement the basic structure for trading agent. diff --git a/docs/developer-docs/docs/build-an-app/build-a-basic-warden-agent/precompiles.md b/docs/developer-docs/docs/build-an-app/build-a-basic-warden-agent/precompiles.md index e76f408d0..e6cf375e7 100644 --- a/docs/developer-docs/docs/build-an-app/build-a-basic-warden-agent/precompiles.md +++ b/docs/developer-docs/docs/build-an-app/build-a-basic-warden-agent/precompiles.md @@ -1,18 +1,33 @@ --- -sidebar_position: 3 +sidebar_position: 4 --- -# Mock Precompiles +# Create mock precompiles -In this section we will create mock precompiles that are essential for testing our Agent end to end. +## Overview -Before you proceed, please create a `mock` directory where these functions will reside. +Mock precompiles are essential for end-to-end testing of the Basic Agent. -## Setting up mock precompiles +This article explains how to build and test two mock precompiles: Slinky and Warden. Before you proceed, create a `/mock` directory for storing them. -### Create `mocks/MockSlinkyPrecompile.sol` +You can learn about mock precompiles in the [Mock Precompiles](https://github.com/warden-protocol/wardenprotocol/tree/main/solidity/orders/mocks) section and test under [Test Scenarios](https://github.com/warden-protocol/wardenprotocol/tree/main/solidity/orders/test). -```solidity + +## 1. Create mock precompiles + +### 1.1. Create a Slinky precompile + +In a file `MockSlinkyPrecompile.sol`, implement a mock Slinky precompile with the following features: + +- Price feed functionality +- Price setting for testing +- Error handling for missing prices + +:::note GitHub +You can find the full code on GitHub: [`/mocks/MockSlinkyPrecompile.sol`](https://github.com/warden-protocol/wardenprotocol/blob/main/solidity/orders/mocks/MockSlinkyPrecompile.sol) +::: + +```solidity title="/mocks/MockSlinkyPrecompile.sol" // SPDX-License-Identifier: GPL-3.0 pragma solidity >=0.8.25 <0.9.0; @@ -28,9 +43,9 @@ contract MockSlinkyPrecompile is ISlinky { uint256 price = prices[base][quote]; require(price != 0, "Price not set"); - // NEW: Enhanced price data with additional metadata + // Price data with additional metadata QuotePrice memory quotePrice = QuotePrice({ - blockHeight: block.number, // Current block for testing + blockHeight: block.number, // The current block for testing blockTimestamp: block.timestamp, price: price }); @@ -45,14 +60,24 @@ contract MockSlinkyPrecompile is ISlinky { } ``` -### Create `mocks/MockWardenPrecompile.sol` +### 1.2. Create a Warden precompile -```solidity +In a file `MockWardenPrecompile.sol`, implement a mock Warden precompile with the following features: + +- Key management +- Managing transaction signing requests +- Key validation + +:::note GitHub +You can find the full code on GitHub: [`/mocks/MockWardenPrecompile.sol`](https://github.com/warden-protocol/wardenprotocol/blob/main/solidity/orders/mocks/MockWardenPrecompile.sol) +::: + +```solidity title="/mocks/MockWardenPrecompile.sol" contract MockWardenPrecompile { mapping(uint64 => KeyResponse) private keys; mapping(uint64 => bool) private goodKeys; - // NEW: Enhanced key response simulation + // A key response simulation function keyById( uint64 id, int32[] calldata @@ -68,7 +93,7 @@ contract MockWardenPrecompile { }); } - // NEW: Realistic signing behavior + // Realistic signing behavior function newSignRequest( uint64 keyId, bytes calldata txHash, @@ -90,23 +115,9 @@ contract MockWardenPrecompile { } ``` -These mock contracts simulate the behavior of: - -**MockSlinkyPrecompile:** - -- Price feed functionality -- Price setting for testing -- Error handling for missing prices +## 2. Implement integration testing -**MockWardenPrecompile:** - -- Key management -- Transaction signing requests -- Key validation - -## Integration Testing - -### Test Setup Helper +Create a helper contract for testing mock precompiles: ```solidity contract PrecompileTestHelper { @@ -123,7 +134,7 @@ contract PrecompileTestHelper { vm.etch(IWARDEN_PRECOMPILE_ADDRESS, address(warden).code); } - // NEW: Price scenario helper + // A price scenario helper function setupPriceScenario( string memory base, string memory quote, @@ -133,7 +144,7 @@ contract PrecompileTestHelper { MockSlinkyPrecompile(ISLINKY_PRECOMPILE_ADDRESS) .setPrice(base, quote, initialPrice); - // Simulate price change + // Simulate a price change skip(1 hours); MockSlinkyPrecompile(ISLINKY_PRECOMPILE_ADDRESS) .setPrice(base, quote, targetPrice); @@ -141,19 +152,21 @@ contract PrecompileTestHelper { } ``` -## Test Scenarios +## 3. Create test scenarios + +### 3.1. Test the price feed -### Price Feed Testing +To create a scenario for testing the price feed, use the following code: ```solidity contract SlinkyTest is PrecompileTestHelper { function testPriceMovement() public { - // Setup price scenario + // Set up a price scenario setupPriceScenario("ETH", "USD", 3000e9, 3500e9); - // Test order execution + // Test the order execution Types.OrderData memory orderData = createTestOrder( - 3200e9, // threshold + 3200e9, // The threshold Types.PriceCondition.GTE ); @@ -174,15 +187,17 @@ contract SlinkyTest is PrecompileTestHelper { } ``` +### 3.2. Test transaction signing + +To create a scenario for testing transaction signing, use the following code: -### Transaction Signing Testing ```solidity contract WardenTest is PrecompileTestHelper { function testSigningFlow() public { - // Setup keys - warden.addKey(1, true); // Valid key - warden.addKey(2, false); // Invalid key + // Set up keys + warden.addKey(1, true); // A valid key + warden.addKey(2, false); // An invalid key // Test successful signing Types.SignRequestData memory goodRequest = createSignRequest(1); @@ -202,7 +217,9 @@ contract WardenTest is PrecompileTestHelper { } ``` -## Usage in Scripts +## 4. Use precompiles in scripts + +This is how you can use precompiles in scripts: ```solidity contract CreateOrder is Script { @@ -211,18 +228,18 @@ contract CreateOrder is Script { Types.PriceCondition priceCondition, Types.PricePair memory pricePair ) public { - // Setup mock precompiles + // Set up mock precompiles MockSlinkyPrecompile mSlinky = new MockSlinkyPrecompile(); MockWardenPrecompile mWarden = new MockWardenPrecompile(); - // Configure initial state + // Configure the initial state vm.etch(ISLINKY_PRECOMPILE_ADDRESS, address(mSlinky).code); mSlinky.setPrice(pricePair.base, pricePair.quote, thresholdPrice); vm.etch(IWARDEN_PRECOMPILE_ADDRESS, address(mWarden).code); mWarden.addKey(1, true); - // Create and verify order + // Create and verify an order vm.broadcast(); BasicOrder order = createOrder(/* params */); require(order.canExecute(), "Order cannot execute"); @@ -230,4 +247,6 @@ contract CreateOrder is Script { } ``` -You can learn about mock precompiles in the [Mock Precompiles](https://github.com/warden-protocol/wardenprotocol/tree/main/solidity/orders/mocks) section and test under [Test Scenarios](https://github.com/warden-protocol/wardenprotocol/tree/main/solidity/orders/test) +## Next steps + +After creating mock precompiles, you can [create the trading Agent](main_contract). diff --git a/docs/developer-docs/docs/build-an-app/build-a-basic-warden-agent/prerequisites.md b/docs/developer-docs/docs/build-an-app/build-a-basic-warden-agent/prerequisites.md new file mode 100644 index 000000000..f8a883fc1 --- /dev/null +++ b/docs/developer-docs/docs/build-an-app/build-a-basic-warden-agent/prerequisites.md @@ -0,0 +1,59 @@ +--- +sidebar_position: 2 +--- + +# Prerequisites + +You are expected to posses the following knowledge: + +- Solidity (especially inheritance, interfaces, events) +- Basic understanding of Uniswap V2 +- Familiarity with price oracles +- Understanding of RLP encoding for transactions + +Environment Setup: + +1. Install required dependencies: + +```bash +forge install OpenZeppelin/openzeppelin-contracts +forge install Uniswap/v2-periphery +``` + +2. Configure foundry.toml: + +```bash +[profile.default] +auto_detect_solc = false +block_timestamp = 1_680_220_800 +bytecode_hash = "none" +evm_version = "paris" +fuzz = { runs = 1_000 } +gas_reports = ["*"] +optimizer = true +optimizer_runs = 10_000 +solc = "0.8.25" + +[fmt] +bracket_spacing = true +int_types = "long" +line_length = 120 +multiline_func_header = "all" +number_underscore = "thousands" +quote_style = "double" +tab_width = 4 +wrap_comments = true +``` + +Directory Structure: + +```bash + uniswap-trading-agent +warden-trading-agent/ +├── src/ # Core contracts +├── scripts/ # Deployment scripts +├── test/ # Test files +└── mocks/ # Mock services +``` + +In the next chapter you will learn how to implement the basic structure for trading agent. diff --git a/docs/developer-docs/docs/build-an-app/build-a-basic-warden-agent/structure.md b/docs/developer-docs/docs/build-an-app/build-a-basic-warden-agent/structure.md index edac925dd..718d50480 100644 --- a/docs/developer-docs/docs/build-an-app/build-a-basic-warden-agent/structure.md +++ b/docs/developer-docs/docs/build-an-app/build-a-basic-warden-agent/structure.md @@ -1,35 +1,43 @@ --- -sidebar_position: 2 +sidebar_position: 3 --- -# Trading Agent Structure +# Create the trading Agent structure -Let's build the foundation of our trading agent by implementing the core data structures and interfaces. +## Overview -## Define Trading Types (`src/Types.sol`) +The main part of the Basic Warden Agent is the trading Agent executing orders created by users. -First, let's create our essential data structures. +This article will guide you through building a foundation for the trading Agent: you'll implement the core data structures and interfaces in the `/src` directory. -```solidity +## 1. Define trading types + +First, create a library `Types.sol` with the core data structures: + +:::note GitHub +You can find the full code on GitHub: [`/src/Types.sol`](https://github.com/warden-protocol/wardenprotocol/blob/main/solidity/orders/src/Types.sol) +::: + +```solidity title="/src/Types.sol" library Types { // Define swap parameters for Uniswap struct SwapData { - uint256 amountIn; // Amount of input token - address[] path; // Trading path through Uniswap - address to; // Recipient address - uint256 deadline; // Transaction deadline + uint256 amountIn; // The amount of input tokens + address[] path; // The trading path through Uniswap + address to; // The recipient address + uint256 deadline; // The transaction deadline } - // NEW: Price condition enum for flexible trading + // A price condition for flexible trading enum PriceCondition { LTE, // Less than or equal to threshold GTE // Greater than or equal to threshold } - // Main order configuration + // The main order configuration struct OrderData { uint256 thresholdPrice; - PriceCondition priceCondition; // NEW: Price condition type + PriceCondition priceCondition; PricePair pricePair; CreatorDefinedTxFields creatorDefinedTxFields; SwapData swapData; @@ -38,49 +46,55 @@ library Types { } ``` -[Code Reference](https://github.com/warden-protocol/wardenprotocol/blob/main/solidity/orders/src/Types.sol) +## 2. Create the execution interface -## Create Execution Interface (`src/IExecution.sol`) +The execution interface defines the trading Agent's core functionality. It allows executing an order, getting a list of authorized callers, and checking the execution status. -The execution interface defines the core functionality of our agent with new security and validation features: +Implement the execution interface in a file `IExecution.sol`: -```solidity +:::note GitHub +You can find the full code on GitHub: [`/src/IExecution.sol`](https://github.com/warden-protocol/wardenprotocol/blob/main/solidity/orders/src/IExecution.sol) +::: + +```solidity title="/src/IExecution.sol" interface IExecution { - // Check if order can execute based on conditions + // Check whether an order can be executed function canExecute() external view returns (bool); - // Execute trade with enhanced security parameters + // Execute an order function execute( uint256 nonce, uint256 gas, uint256 gasPrice, - uint256 maxPriorityFeePerGas, // NEW: EIP-1559 support - uint256 maxFeePerGas // NEW: EIP-1559 support + uint256 maxPriorityFeePerGas, // for EIP-1559 transactions + uint256 maxFeePerGas // for EIP-1559 transactions ) external returns (bool, bytes32); - // NEW: Get list of authorized callers + // Get a list of authorized callers function callers() external returns (Caller[] memory callersList); - // Check execution status + // Check the execution status function isExecuted() external returns (bool); } ``` -[Code Reference](https://github.com/warden-protocol/wardenprotocol/blob/main/solidity/orders/src/IExecution.sol) +## 3. Implement the registry -## Registry Implementation (`src/Registry.sol`) +In a file `Registry.sol`, implement a registry for tracking transactions: -The registry now includes enhanced security features and better transaction tracking: +:::note GitHub +You can find the full code on GitHub: [`/src/Registry.sol`](https://github.com/warden-protocol/wardenprotocol/blob/main/solidity/orders/src/Registry.sol) +::: -```solidity +```solidity title="/src/Registry.sol" contract Registry is ReentrancyGuard { // NEW: Added ReentrancyGuard - // Track agent creators + // Track the order creators mapping(address executionAddress => address orderCreator) public executions; - // Store transaction data + // Store the transaction data mapping(bytes32 txHash => bytes tx) public transactions; - // NEW: Enhanced registration with validation + // Register an order with additional validation function register(address execution) public { if (execution == address(0)) { revert InvalidExecutionAddress(); @@ -93,15 +107,17 @@ contract Registry is ReentrancyGuard { // NEW: Added ReentrancyGuard } ``` -[Code Reference](https://github.com/warden-protocol/wardenprotocol/blob/main/solidity/orders/src/Registry.sol) +## 4. Implement the RLP encoding -## RLP Transaction Encoding (`src/RLPEncode.sol`) +To support EIP-1559 transactions, create an `RLPEncode.sol` file implementing the RLP encoding: -Implement RLP encoding for EIP-1559 transaction support: +:::note GitHub +You can find the full code on GitHub: [`/src/RLPEncode.sol`](https://github.com/warden-protocol/wardenprotocol/blob/main/solidity/orders/src/RLPEncode.sol) +::: -```solidity +```solidity title="/src/RLPEncode.sol" library RLPEncode { - // NEW: Enhanced encoding for EIP-1559 transactions + // Implement the RLP encoding for EIP-1559 transactions function encodeTransaction( Types.OrderData memory orderData, uint256 nonce, @@ -116,4 +132,6 @@ library RLPEncode { } ``` -[Code Reference](https://github.com/warden-protocol/wardenprotocol/blob/main/solidity/orders/src/RLPEncode.sol) +## Next steps + +After building the structure of the trading Agent, you can [create mock precompiles](precompiles).