Skip to content

Commit

Permalink
chore: move SmartSellOrder into SmartOrder.t.sol
Browse files Browse the repository at this point in the history
  • Loading branch information
meetmangukiya committed Oct 8, 2024
1 parent 7ee4eab commit 489cf7d
Show file tree
Hide file tree
Showing 2 changed files with 101 additions and 109 deletions.
102 changes: 101 additions & 1 deletion test/e2e/SmartOrder.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,116 @@ pragma solidity ^0.8;

import {Vm} from "forge-std/Vm.sol";

import {GPv2Settlement} from "src/contracts/GPv2Settlement.sol";
import {EIP1271Verifier, GPv2EIP1271} from "src/contracts/interfaces/GPv2EIP1271.sol";
import {IERC20} from "src/contracts/interfaces/IERC20.sol";
import {GPv2Order} from "src/contracts/libraries/GPv2Order.sol";
import {GPv2SafeERC20} from "src/contracts/libraries/GPv2SafeERC20.sol";
import {SafeMath} from "src/contracts/libraries/SafeMath.sol";
import {GPv2Signing} from "src/contracts/mixins/GPv2Signing.sol";

import {Sign} from "../libraries/Sign.sol";
import {SettlementEncoder} from "../libraries/encoders/SettlementEncoder.sol";
import {Registry, TokenRegistry} from "../libraries/encoders/TokenRegistry.sol";
import {SmartSellOrder} from "../src/SmartSellOrder.sol";
import {Helper, IERC20Mintable} from "./Helper.sol";

/// @title Proof of Concept Smart Order
/// @author Gnosis Developers
contract SmartSellOrder is EIP1271Verifier {
using GPv2Order for GPv2Order.Data;
using GPv2SafeERC20 for IERC20;
using SafeMath for uint256;

bytes32 public constant APPDATA = keccak256("SmartSellOrder");

address public immutable owner;
bytes32 public immutable domainSeparator;
IERC20 public immutable sellToken;
IERC20 public immutable buyToken;
uint256 public immutable totalSellAmount;
uint256 public immutable totalFeeAmount;
uint32 public immutable validTo;

constructor(
GPv2Settlement settlement,
IERC20 sellToken_,
IERC20 buyToken_,
uint32 validTo_,
uint256 totalSellAmount_,
uint256 totalFeeAmount_
) {
owner = msg.sender;
domainSeparator = settlement.domainSeparator();
sellToken = sellToken_;
buyToken = buyToken_;
validTo = validTo_;
totalSellAmount = totalSellAmount_;
totalFeeAmount = totalFeeAmount_;

sellToken_.approve(address(settlement.vaultRelayer()), type(uint256).max);
}

modifier onlyOwner() {
require(msg.sender == owner, "not owner");
_;
}

function withdraw(uint256 amount) external onlyOwner {
sellToken.safeTransfer(owner, amount);
}

function close() external onlyOwner {
uint256 balance = sellToken.balanceOf(address(this));
if (balance != 0) {
sellToken.safeTransfer(owner, balance);
}
}

function isValidSignature(bytes32 hash, bytes memory signature)
external
view
override
returns (bytes4 magicValue)
{
uint256 sellAmount = abi.decode(signature, (uint256));
GPv2Order.Data memory order = orderForSellAmount(sellAmount);

if (order.hash(domainSeparator) == hash) {
magicValue = GPv2EIP1271.MAGICVALUE;
}
}

function orderForSellAmount(uint256 sellAmount) public view returns (GPv2Order.Data memory order) {
order.sellToken = sellToken;
order.buyToken = buyToken;
order.receiver = owner;
order.sellAmount = sellAmount;
order.buyAmount = buyAmountForSellAmount(sellAmount);
order.validTo = validTo;
order.appData = APPDATA;
order.feeAmount = totalFeeAmount.mul(sellAmount).div(totalSellAmount);
order.kind = GPv2Order.KIND_SELL;
// NOTE: We counter-intuitively set `partiallyFillable` to `false`, even
// if the smart order as a whole acts like a partially fillable order.
// This is done since, once a settlement commits to a specific sell
// amount, then it is expected to use it completely and not partially.
order.partiallyFillable = false;
order.sellTokenBalance = GPv2Order.BALANCE_ERC20;
order.buyTokenBalance = GPv2Order.BALANCE_ERC20;
}

function buyAmountForSellAmount(uint256 sellAmount) private view returns (uint256 buyAmount) {
uint256 feeAdjustedBalance =
sellToken.balanceOf(address(this)).mul(totalSellAmount).div(totalSellAmount.add(totalFeeAmount));
uint256 soldAmount = totalSellAmount > feeAdjustedBalance ? totalSellAmount - feeAdjustedBalance : 0;

// NOTE: This is currently a silly price strategy where the xrate
// increases linearly from 1:1 to 1:2 as the smart order gets filled.
// This can be extended to more complex "price curves".
buyAmount = sellAmount.mul(totalSellAmount.add(sellAmount).add(soldAmount)).div(totalSellAmount);
}
}

using SettlementEncoder for SettlementEncoder.State;
using TokenRegistry for TokenRegistry.State;
using TokenRegistry for Registry;
Expand Down
108 changes: 0 additions & 108 deletions test/src/SmartSellOrder.sol

This file was deleted.

0 comments on commit 489cf7d

Please sign in to comment.