feat: Add permit2 draft
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
mod approvals_manager;
|
mod approvals_manager;
|
||||||
mod models;
|
mod models;
|
||||||
|
mod permit2;
|
||||||
mod router_encoder;
|
mod router_encoder;
|
||||||
mod strategy_encoder;
|
mod strategy_encoder;
|
||||||
mod swap_encoder;
|
mod swap_encoder;
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ pub struct Order {
|
|||||||
/// True if the order is an exact output order.
|
/// True if the order is an exact output order.
|
||||||
pub exact_out: bool,
|
pub exact_out: bool,
|
||||||
/// The token being sold (exact in) or bought (exact out).
|
/// The token being sold (exact in) or bought (exact out).
|
||||||
given_token: Bytes,
|
pub given_token: Bytes,
|
||||||
/// Amount of the given token.
|
/// Amount of the given token.
|
||||||
pub given_amount: BigUint,
|
pub given_amount: BigUint,
|
||||||
/// The token being bought (exact in) or sold (exact out).
|
/// The token being bought (exact in) or sold (exact out).
|
||||||
@@ -26,7 +26,7 @@ pub struct Order {
|
|||||||
/// Amount of the checked token.
|
/// Amount of the checked token.
|
||||||
checked_amount: BigUint,
|
checked_amount: BigUint,
|
||||||
/// Address of the sender.
|
/// Address of the sender.
|
||||||
sender: Bytes,
|
pub sender: Bytes,
|
||||||
/// Address of the receiver.
|
/// Address of the receiver.
|
||||||
pub receiver: Bytes,
|
pub receiver: Bytes,
|
||||||
/// List of swaps to fulfill the order.
|
/// List of swaps to fulfill the order.
|
||||||
|
|||||||
44
src/encoding/permit2.rs
Normal file
44
src/encoding/permit2.rs
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
use alloy_primitives::{Address, U256};
|
||||||
|
use num_bigint::BigUint;
|
||||||
|
use std::str::FromStr;
|
||||||
|
use tycho_core::Bytes;
|
||||||
|
|
||||||
|
pub struct PermitRequest {
|
||||||
|
pub token: Bytes,
|
||||||
|
pub amount: BigUint,
|
||||||
|
pub spender: Bytes,
|
||||||
|
pub router_address: Address,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Permit2 {
|
||||||
|
pub address: Address,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Permit2 {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
address: Address::from_str("0x000000000022D473030F116dDEE9F6B43aC78BA3")
|
||||||
|
.expect("Permit2 address not valid"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn encode_permit(&self, details: Vec<PermitRequest>) -> Vec<u8> {
|
||||||
|
// calls get_allowance_data to get nonce
|
||||||
|
// checks if we are not permitted already
|
||||||
|
// puts data into a permitSingle struct if there is only 1 PermitDetails, if there are several, use PermitBatch
|
||||||
|
// adds the nonce and the expiration (uniswap recommends 30 days for expiration)
|
||||||
|
// signs data
|
||||||
|
// returns encoded data
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_allowance_data(
|
||||||
|
&self,
|
||||||
|
user: Address,
|
||||||
|
router_address: Address,
|
||||||
|
token: Address,
|
||||||
|
) -> (U256, u64, U256) {
|
||||||
|
// get allowance data (if it exists) and the nonce
|
||||||
|
// returns permitAmount, expiration, nonce
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
use crate::encoding::models::{Order, Solution};
|
use crate::encoding::models::{Order, Solution};
|
||||||
|
use crate::encoding::permit2::{Permit2, PermitRequest};
|
||||||
use crate::encoding::strategy_encoder::{
|
use crate::encoding::strategy_encoder::{
|
||||||
SequentialExactInStrategyEncoder, SingleSwapStrategyEncoder, SlipSwapStrategyEncoder,
|
SequentialExactInStrategyEncoder, SingleSwapStrategyEncoder, SlipSwapStrategyEncoder,
|
||||||
StrategyEncoder,
|
StrategyEncoder,
|
||||||
@@ -24,6 +25,7 @@ impl RouterEncoder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn encode_router_calldata(&self, solution: Solution) -> Result<Vec<u8>, Error> {
|
pub fn encode_router_calldata(&self, solution: Solution) -> Result<Vec<u8>, Error> {
|
||||||
|
let permit_calldata = self.handle_approvals(&solution)?; // TODO: where should we append this?
|
||||||
let mut calldata_list: Vec<Vec<u8>> = Vec::new();
|
let mut calldata_list: Vec<Vec<u8>> = Vec::new();
|
||||||
let encode_for_batch_execute = solution.orders.len() > 1;
|
let encode_for_batch_execute = solution.orders.len() > 1;
|
||||||
for order in solution.orders {
|
for order in solution.orders {
|
||||||
@@ -47,6 +49,19 @@ impl RouterEncoder {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn handle_approvals(&self, solution: &Solution) -> Result<Vec<u8>, Error> {
|
||||||
|
let mut permits = Vec::new();
|
||||||
|
for order in solution.orders.iter() {
|
||||||
|
permits.push(PermitRequest {
|
||||||
|
token: order.given_token.clone(),
|
||||||
|
spender: order.sender.clone(),
|
||||||
|
amount: order.given_amount.clone(),
|
||||||
|
router_address: solution.router_address.unwrap_or(self.router_address),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
Ok(Permit2::new().encode_permit(permits))
|
||||||
|
}
|
||||||
|
|
||||||
fn get_strategy(&self, order: &Order) -> &dyn StrategyEncoder {
|
fn get_strategy(&self, order: &Order) -> &dyn StrategyEncoder {
|
||||||
if order.swaps.len() == 1 {
|
if order.swaps.len() == 1 {
|
||||||
&SingleSwapStrategyEncoder {}
|
&SingleSwapStrategyEncoder {}
|
||||||
|
|||||||
Reference in New Issue
Block a user