pragma solidity ^0.8.20;
import {Vm, Test} from "forge-std/Test.sol";
import {console2} from "forge-std/console2.sol";
import {Swan} from "../src/swan/Swan.sol";
import {BuyerAgent} from "../src/swan/BuyerAgent.sol";
import {LLMOracleCoordinator} from "../src/llm/LLMOracleCoordinator.sol";
import {LLMOracleRegistry, LLMOracleKind} from "../src/llm/LLMOracleRegistry.sol";
import {MockToken} from "./mock/MockToken.sol";
import {ERC1967Proxy} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol";
import {LLMOracleTaskParameters, LLMOracleTask} from "../src/llm/LLMOracleTask.sol";
import {IERC20Errors} from "@openzeppelin/contracts/interfaces/draft-IERC6093.sol";
import {SwanMarketParameters} from "../src/swan/SwanManager.sol";
import {SwanAssetFactory, SwanAsset} from "../src/swan/SwanAsset.sol";
contract BaseTest is Test {
LLMOracleRegistry registry;
LLMOracleCoordinator coordinator;
MockToken mocktoken;
Swan swan;
BuyerAgent buyerAgent;
address requester = makeAddr("requester");
address responder = makeAddr("responder");
address buyer = makeAddr("buyer");
function setUp() public {
LLMOracleRegistry registryImpl = new LLMOracleRegistry();
mocktoken = new MockToken("Mock Token", "MT");
uint256 generatorStake = 1;
bytes memory _data = abi.encodeWithSignature(
"initialize(uint256,uint256,address)",
generatorStake,
0,
address(mocktoken)
);
ERC1967Proxy registryProxy = new ERC1967Proxy(
address(registryImpl),
_data
);
registry = LLMOracleRegistry(address(registryProxy));
LLMOracleCoordinator coordinatorImpl = new LLMOracleCoordinator();
uint256 _platformFee = 0.1 ether;
uint256 _generationFee = 0.1 ether;
uint256 _validationFee = 0.1 ether;
_data = abi.encodeWithSignature(
"initialize(address,address,uint256,uint256,uint256)",
address(registry),
address(mocktoken),
_platformFee,
_generationFee,
_validationFee
);
ERC1967Proxy coordinatorProxy = new ERC1967Proxy(
address(coordinatorImpl),
_data
);
coordinator = LLMOracleCoordinator(address(coordinatorProxy));
deploySwanAndAgent();
}
function deploySwanAndAgent() public {
SwanAssetFactory assetFactory = new SwanAssetFactory();
Swan swanImpl = new Swan();
SwanMarketParameters memory marketParams = SwanMarketParameters({
withdrawInterval: uint256(1 weeks),
sellInterval: uint256(1 weeks),
buyInterval: uint256(1 weeks),
platformFee: uint256(1),
maxAssetCount: uint256(100),
timestamp: uint256(block.timestamp)
});
LLMOracleTaskParameters memory oracleParams = LLMOracleTaskParameters({
difficulty: uint8(1),
numGenerations: uint40(1),
numValidations: uint40(0)
});
bytes memory _data = abi.encodeWithSelector(
Swan(address(swanImpl)).initialize.selector,
marketParams,
oracleParams,
address(coordinator),
address(mocktoken),
address(1),
assetFactory
);
ERC1967Proxy swanProxy = new ERC1967Proxy(address(swanImpl), _data);
swan = Swan(address(swanProxy));
string memory _name = "buyer agent";
string memory _description = "buyer agent";
uint96 _royaltyFee = 1;
uint256 _amountPerRound = 1 ether;
address _operator = address(swan);
address _owner = buyer;
buyerAgent = new BuyerAgent(
_name,
_description,
_royaltyFee,
_amountPerRound,
_operator,
_owner
);
}
function testUpdateStateAfterWithdraw() public {
uint256 fundAmount = 10 ether;
deal(address(mocktoken), address(buyerAgent), fundAmount);
vm.warp(block.timestamp + 2 weeks + 1);
vm.startPrank(buyer);
uint256 minFundAmount = (buyerAgent.minFundAmount());
buyerAgent.withdraw(uint96(fundAmount - minFundAmount));
bytes memory input = "input";
bytes memory models = "models";
buyerAgent.oracleStateRequest(input, models);
vm.stopPrank();
vm.warp(block.timestamp + 1 weeks);
mockTokenListAndOracleResponse(buyerAgent.amountPerRound());
vm.expectRevert();
buyerAgent.purchase();
}
function mockTokenListAndOracleResponse(uint256 price) public {
string memory _name = "asset";
string memory _symbol = "asset";
bytes memory _desc = "description";
uint256 _price = price;
address _buyer = address(buyerAgent);
mocktoken.approve(address(swan), type(uint256).max);
vm.recordLogs();
swan.list(_name, _symbol, _desc, _price, _buyer);
Vm.Log[] memory entries = vm.getRecordedLogs();
bytes32 assetAddr = entries[6].topics[2];
bytes32[] memory assetAddrArr = new bytes32[]();
assetAddrArr[0] = assetAddr;
vm.warp(block.timestamp + 1 weeks + 1);
bytes memory input = "input";
bytes memory models = "models";
vm.startPrank(buyer);
buyerAgent.oraclePurchaseRequest(input, models);
vm.stopPrank();
deal(address(mocktoken), responder, 1 ether);
vm.startPrank(responder);
mocktoken.approve(address(registry), type(uint256).max);
LLMOracleKind oracleKind = LLMOracleKind.Generator;
registry.register(oracleKind);
uint256 taskId = 2;
uint256 nonce = 123456;
bytes memory output = abi.encode(assetAddrArr);
coordinator.respond(taskId, nonce, output, models);
vm.stopPrank();
}
}