From 7dcc2b4d93b5a307001b70e9a9c77b198f6c9d96 Mon Sep 17 00:00:00 2001 From: Bryan Stitt Date: Wed, 31 May 2023 11:52:51 -0700 Subject: [PATCH] use MultiAbigen --- Cargo.lock | 9 + Cargo.toml | 1 + payment-contracts/.gitignore | 1 + payment-contracts/Cargo.toml | 13 + payment-contracts/abi/IERC20.json | 244 +++++++++++ payment-contracts/abi/PaymentFactory.json | 477 ++++++++++++++++++++++ payment-contracts/abi/PaymentProxy.json | 29 ++ payment-contracts/abi/PaymentSweeper.json | 65 +++ payment-contracts/build.rs | 17 + payment-contracts/src/lib.rs | 3 + web3_proxy/Cargo.toml | 1 + web3_proxy/src/frontend/users/payment.rs | 32 +- 12 files changed, 864 insertions(+), 28 deletions(-) create mode 100644 payment-contracts/.gitignore create mode 100644 payment-contracts/Cargo.toml create mode 100644 payment-contracts/abi/IERC20.json create mode 100644 payment-contracts/abi/PaymentFactory.json create mode 100644 payment-contracts/abi/PaymentProxy.json create mode 100644 payment-contracts/abi/PaymentSweeper.json create mode 100644 payment-contracts/build.rs create mode 100644 payment-contracts/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index 0521ae1f..28ccecd6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3613,6 +3613,14 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e91099d4268b0e11973f036e885d652fb0b21fedcf69738c627f94db6a44f42" +[[package]] +name = "payment-contracts" +version = "0.1.0" +dependencies = [ + "ethers", + "glob", +] + [[package]] name = "pbkdf2" version = "0.11.0" @@ -6528,6 +6536,7 @@ dependencies = [ "ordered-float", "pagerduty-rs", "parking_lot 0.12.1", + "payment-contracts", "prettytable", "proctitle", "quick_cache_ttl", diff --git a/Cargo.toml b/Cargo.toml index 12175b98..d777eb3f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,6 +4,7 @@ members = [ "entities", "latency", "migration", + "payment-contracts", "quick_cache_ttl", "rate-counter", "redis-rate-limiter", diff --git a/payment-contracts/.gitignore b/payment-contracts/.gitignore new file mode 100644 index 00000000..2f6e0283 --- /dev/null +++ b/payment-contracts/.gitignore @@ -0,0 +1 @@ +/src/contracts/*.rs \ No newline at end of file diff --git a/payment-contracts/Cargo.toml b/payment-contracts/Cargo.toml new file mode 100644 index 00000000..30ba64a1 --- /dev/null +++ b/payment-contracts/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "payment-contracts" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[build-dependencies] +ethers = "2.0.6" +glob = "0.3.1" + +[dependencies] +ethers = "2.0.6" diff --git a/payment-contracts/abi/IERC20.json b/payment-contracts/abi/IERC20.json new file mode 100644 index 00000000..51b4bb73 --- /dev/null +++ b/payment-contracts/abi/IERC20.json @@ -0,0 +1,244 @@ +[ + { + "name": "Transfer", + "inputs": [ + { + "name": "_from", + "type": "address", + "indexed": true + }, + { + "name": "_to", + "type": "address", + "indexed": true + }, + { + "name": "_value", + "type": "uint256", + "indexed": false + } + ], + "anonymous": false, + "type": "event" + }, + { + "name": "Approval", + "inputs": [ + { + "name": "_owner", + "type": "address", + "indexed": true + }, + { + "name": "_spender", + "type": "address", + "indexed": true + }, + { + "name": "_value", + "type": "uint256", + "indexed": false + } + ], + "anonymous": false, + "type": "event" + }, + { + "stateMutability": "nonpayable", + "type": "constructor", + "inputs": [ + { + "name": "_name", + "type": "string" + }, + { + "name": "_symbol", + "type": "string" + }, + { + "name": "_decimals", + "type": "uint256" + } + ], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "transfer", + "inputs": [ + { + "name": "_to", + "type": "address" + }, + { + "name": "_value", + "type": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "gas": 79588 + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "transferFrom", + "inputs": [ + { + "name": "_from", + "type": "address" + }, + { + "name": "_to", + "type": "address" + }, + { + "name": "_value", + "type": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "gas": 119640 + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "approve", + "inputs": [ + { + "name": "_spender", + "type": "address" + }, + { + "name": "_value", + "type": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "gas": 37791 + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "_mint_for_testing", + "inputs": [ + { + "name": "_target", + "type": "address" + }, + { + "name": "_value", + "type": "uint256" + } + ], + "outputs": [], + "gas": 77251 + }, + { + "stateMutability": "view", + "type": "function", + "name": "name", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "string" + } + ], + "gas": 12810 + }, + { + "stateMutability": "view", + "type": "function", + "name": "symbol", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "string" + } + ], + "gas": 10563 + }, + { + "stateMutability": "view", + "type": "function", + "name": "decimals", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "gas": 2568 + }, + { + "stateMutability": "view", + "type": "function", + "name": "balanceOf", + "inputs": [ + { + "name": "arg0", + "type": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "gas": 2813 + }, + { + "stateMutability": "view", + "type": "function", + "name": "allowance", + "inputs": [ + { + "name": "arg0", + "type": "address" + }, + { + "name": "arg1", + "type": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "gas": 3058 + }, + { + "stateMutability": "view", + "type": "function", + "name": "totalSupply", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "gas": 2658 + } +] \ No newline at end of file diff --git a/payment-contracts/abi/PaymentFactory.json b/payment-contracts/abi/PaymentFactory.json new file mode 100644 index 00000000..b92fcc1d --- /dev/null +++ b/payment-contracts/abi/PaymentFactory.json @@ -0,0 +1,477 @@ +[ + { + "name": "NewPaymentAddress", + "inputs": [ + { + "name": "account", + "type": "address", + "indexed": false + }, + { + "name": "payment_address", + "type": "address", + "indexed": false + } + ], + "anonymous": false, + "type": "event" + }, + { + "name": "PaymentReceived", + "inputs": [ + { + "name": "account", + "type": "address", + "indexed": false + }, + { + "name": "token", + "type": "address", + "indexed": false + }, + { + "name": "amount", + "type": "uint256", + "indexed": false + } + ], + "anonymous": false, + "type": "event" + }, + { + "name": "NewOwnerCommitted", + "inputs": [ + { + "name": "owner", + "type": "address", + "indexed": false + }, + { + "name": "new_owner", + "type": "address", + "indexed": false + }, + { + "name": "finalize_time", + "type": "uint256", + "indexed": false + } + ], + "anonymous": false, + "type": "event" + }, + { + "name": "NewOwnerAccepted", + "inputs": [ + { + "name": "old_owner", + "type": "address", + "indexed": false + }, + { + "name": "owner", + "type": "address", + "indexed": false + } + ], + "anonymous": false, + "type": "event" + }, + { + "name": "NewSweeperCommitted", + "inputs": [ + { + "name": "sweeper", + "type": "address", + "indexed": false + }, + { + "name": "new_sweeper", + "type": "address", + "indexed": false + }, + { + "name": "finalize_time", + "type": "uint256", + "indexed": false + } + ], + "anonymous": false, + "type": "event" + }, + { + "name": "NewSweeperSet", + "inputs": [ + { + "name": "old_sweeper", + "type": "address", + "indexed": false + }, + { + "name": "sweeper", + "type": "address", + "indexed": false + } + ], + "anonymous": false, + "type": "event" + }, + { + "name": "NewReceiverCommitted", + "inputs": [ + { + "name": "receiver", + "type": "address", + "indexed": false + }, + { + "name": "new_receiver", + "type": "address", + "indexed": false + }, + { + "name": "finalize_time", + "type": "uint256", + "indexed": false + } + ], + "anonymous": false, + "type": "event" + }, + { + "name": "NewReceiverSet", + "inputs": [ + { + "name": "old_receiver", + "type": "address", + "indexed": false + }, + { + "name": "receiver", + "type": "address", + "indexed": false + } + ], + "anonymous": false, + "type": "event" + }, + { + "stateMutability": "nonpayable", + "type": "constructor", + "inputs": [ + { + "name": "_owner", + "type": "address" + }, + { + "name": "_receiver", + "type": "address" + }, + { + "name": "_sweeper", + "type": "address" + }, + { + "name": "_proxy", + "type": "address" + } + ], + "outputs": [] + }, + { + "stateMutability": "view", + "type": "function", + "name": "get_approved_tokens", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address[]" + } + ] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "payment_received", + "inputs": [ + { + "name": "_token", + "type": "address" + }, + { + "name": "_amount", + "type": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "bool" + } + ] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "create_payment_address", + "inputs": [], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "create_payment_address", + "inputs": [ + { + "name": "_account", + "type": "address" + } + ], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "set_token_approvals", + "inputs": [ + { + "name": "_tokens", + "type": "address[]" + }, + { + "name": "_approved", + "type": "bool" + } + ], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "commit_new_sweeper_implementation", + "inputs": [ + { + "name": "_sweeper", + "type": "address" + } + ], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "finalize_new_sweeper_implementation", + "inputs": [], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "commit_new_receiver", + "inputs": [ + { + "name": "_receiver", + "type": "address" + } + ], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "finalize_new_receiver", + "inputs": [], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "commit_transfer_ownership", + "inputs": [ + { + "name": "_new_owner", + "type": "address" + } + ], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "accept_transfer_ownership", + "inputs": [], + "outputs": [] + }, + { + "stateMutability": "view", + "type": "function", + "name": "PROXY_IMPLEMENTATION", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "sweeper_implementation", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "future_sweeper_implementation", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "owner", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "future_owner", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "receiver", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "future_receiver", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "transfer_ownership_timestamp", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "new_sweeper_timestamp", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "new_receiver_timestamp", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "is_approved_token", + "inputs": [ + { + "name": "arg0", + "type": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "bool" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "account_to_payment_address", + "inputs": [ + { + "name": "arg0", + "type": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "address" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "payment_address_to_account", + "inputs": [ + { + "name": "arg0", + "type": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "address" + } + ] + } +] \ No newline at end of file diff --git a/payment-contracts/abi/PaymentProxy.json b/payment-contracts/abi/PaymentProxy.json new file mode 100644 index 00000000..d2cfe4c8 --- /dev/null +++ b/payment-contracts/abi/PaymentProxy.json @@ -0,0 +1,29 @@ +[ + { + "stateMutability": "nonpayable", + "type": "constructor", + "inputs": [ + { + "name": "_factory", + "type": "address" + } + ], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "fallback" + }, + { + "stateMutability": "view", + "type": "function", + "name": "implementation", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address" + } + ] + } +] \ No newline at end of file diff --git a/payment-contracts/abi/PaymentSweeper.json b/payment-contracts/abi/PaymentSweeper.json new file mode 100644 index 00000000..a9086280 --- /dev/null +++ b/payment-contracts/abi/PaymentSweeper.json @@ -0,0 +1,65 @@ +[ + { + "stateMutability": "nonpayable", + "type": "constructor", + "inputs": [ + { + "name": "_factory", + "type": "address" + } + ], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "send_token", + "inputs": [ + { + "name": "_token", + "type": "address" + }, + { + "name": "_amount", + "type": "uint256" + } + ], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "sweep_token_balance", + "inputs": [ + { + "name": "_token", + "type": "address" + } + ], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "recover_token_balance", + "inputs": [ + { + "name": "_token", + "type": "address" + } + ], + "outputs": [] + }, + { + "stateMutability": "view", + "type": "function", + "name": "FACTORY", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address" + } + ] + } +] \ No newline at end of file diff --git a/payment-contracts/build.rs b/payment-contracts/build.rs new file mode 100644 index 00000000..52a01972 --- /dev/null +++ b/payment-contracts/build.rs @@ -0,0 +1,17 @@ +use ethers::contract::MultiAbigen; +use glob::glob; + +fn main() { + // Tell Cargo that if the given file changes, to rerun this build script. + glob("./abi/*.json").unwrap().for_each(|x| { + if let Ok(x) = x { + println!("cargo:rerun-if-changed={:?}", x); + } + }); + + let gen = MultiAbigen::from_json_files("./abi").unwrap(); + + let bindings = gen.build().unwrap(); + + bindings.write_to_module("./src/contracts", false).unwrap(); +} diff --git a/payment-contracts/src/lib.rs b/payment-contracts/src/lib.rs new file mode 100644 index 00000000..3121d884 --- /dev/null +++ b/payment-contracts/src/lib.rs @@ -0,0 +1,3 @@ +mod contracts; + +pub use contracts::*; diff --git a/web3_proxy/Cargo.toml b/web3_proxy/Cargo.toml index a751e96a..47258e44 100644 --- a/web3_proxy/Cargo.toml +++ b/web3_proxy/Cargo.toml @@ -19,6 +19,7 @@ deferred-rate-limiter = { path = "../deferred-rate-limiter" } entities = { path = "../entities" } latency = { path = "../latency" } migration = { path = "../migration" } +payment-contracts = { path = "../payment-contracts" } quick_cache_ttl = { path = "../quick_cache_ttl" } redis-rate-limiter = { path = "../redis-rate-limiter" } thread-fast-rng = { path = "../thread-fast-rng" } diff --git a/web3_proxy/src/frontend/users/payment.rs b/web3_proxy/src/frontend/users/payment.rs index c2039c06..3933e869 100644 --- a/web3_proxy/src/frontend/users/payment.rs +++ b/web3_proxy/src/frontend/users/payment.rs @@ -11,46 +11,22 @@ use axum_macros::debug_handler; use entities::{balance, increase_on_chain_balance_receipt, user}; use ethbloom::Input as BloomInput; use ethers::abi::{AbiEncode, ParamType}; -use ethers::prelude::abigen; use ethers::types::{Address, TransactionReceipt, H256, U256}; use hashbrown::HashMap; use http::StatusCode; -use log::{debug, info, trace, warn}; +use log::{debug, info, trace}; use migration::sea_orm::prelude::Decimal; use migration::sea_orm::{ self, ActiveModelTrait, ColumnTrait, EntityTrait, IntoActiveModel, QueryFilter, TransactionTrait, }; use num_traits::Pow; +use payment_contracts::ierc20::IERC20; +use payment_contracts::payment_factory::PaymentFactory; use serde_json::json; use std::str::FromStr; use std::sync::Arc; -// TODO: do this in a build.rs so that the editor autocomplete and docs are better -abigen!( - IERC20, - r#"[ - decimals() external view returns (uint256) - event Transfer(address indexed from, address indexed to, uint256 value) - event Approval(address indexed owner, address indexed spender, uint256 value) - ]"#, -); - -abigen!( - PaymentFactory, - r#"[ - event PaymentReceived(address indexed account, address token, uint256 amount) - account_to_payment_address(address) external view returns (address) - payment_address_to_account(address) external view returns (address) - ]"#, -); - -abigen!( - PaymentSweeper, - r#"[ - ]"#, -); - /// Implements any logic related to payments /// Removed this mainly from "user" as this was getting clogged /// @@ -152,7 +128,7 @@ pub async fn user_balance_post( let db_conn = app.db_conn().context("query_user_stats needs a db")?; - // Return straight false if the tx was already added ... + // Return early if the tx was already added if increase_on_chain_balance_receipt::Entity::find() .filter(increase_on_chain_balance_receipt::Column::TxHash.eq(tx_hash.encode_hex())) .one(&db_conn)