From 63bb804b105dcc2cf3fae835c0a8c6ca3270361d Mon Sep 17 00:00:00 2001 From: Mike Shultz Date: Sun, 24 Jul 2022 20:24:32 -0600 Subject: [PATCH 1/4] feat(origin-dollar): Adds Wrapped OUSD (wOUSD) and Vote Escrowed OGV (veOGV) --- .../origin-dollar/contracts/abis/veogv.json | 419 ++++++ .../origin-dollar/contracts/abis/wousd.json | 327 +++++ .../origin-dollar/contracts/ethers/Veogv.ts | 1196 +++++++++++++++++ .../origin-dollar/contracts/ethers/Wousd.ts | 943 +++++++++++++ .../origin-dollar/contracts/ethers/common.ts | 32 + .../ethers/factories/Veogv__factory.ts | 999 ++++++++++++++ .../ethers/factories/Wousd__factory.ts | 810 +++++++++++ .../contracts/ethers/factories/index.ts | 5 + .../origin-dollar/contracts/ethers/index.ts | 8 + src/apps/origin-dollar/contracts/index.ts | 28 + .../ethereum/origin-dollar.balance-fetcher.ts | 64 + ...ollar.rewards.contract-position-fetcher.ts | 54 + .../origin-dollar.veogv.token-fetcher.ts | 129 ++ .../origin-dollar.wousd.token-fetcher.ts | 83 ++ .../helpers/ogv-rewards.balance-helper.ts | 54 + src/apps/origin-dollar/index.ts | 3 + .../origin-dollar/origin-dollar.definition.ts | 51 + .../origin-dollar/origin-dollar.module.ts | 24 + 18 files changed, 5229 insertions(+) create mode 100644 src/apps/origin-dollar/contracts/abis/veogv.json create mode 100644 src/apps/origin-dollar/contracts/abis/wousd.json create mode 100644 src/apps/origin-dollar/contracts/ethers/Veogv.ts create mode 100644 src/apps/origin-dollar/contracts/ethers/Wousd.ts create mode 100644 src/apps/origin-dollar/contracts/ethers/common.ts create mode 100644 src/apps/origin-dollar/contracts/ethers/factories/Veogv__factory.ts create mode 100644 src/apps/origin-dollar/contracts/ethers/factories/Wousd__factory.ts create mode 100644 src/apps/origin-dollar/contracts/ethers/factories/index.ts create mode 100644 src/apps/origin-dollar/contracts/ethers/index.ts create mode 100644 src/apps/origin-dollar/contracts/index.ts create mode 100644 src/apps/origin-dollar/ethereum/origin-dollar.balance-fetcher.ts create mode 100644 src/apps/origin-dollar/ethereum/origin-dollar.rewards.contract-position-fetcher.ts create mode 100644 src/apps/origin-dollar/ethereum/origin-dollar.veogv.token-fetcher.ts create mode 100644 src/apps/origin-dollar/ethereum/origin-dollar.wousd.token-fetcher.ts create mode 100644 src/apps/origin-dollar/helpers/ogv-rewards.balance-helper.ts create mode 100644 src/apps/origin-dollar/index.ts create mode 100644 src/apps/origin-dollar/origin-dollar.definition.ts create mode 100644 src/apps/origin-dollar/origin-dollar.module.ts diff --git a/src/apps/origin-dollar/contracts/abis/veogv.json b/src/apps/origin-dollar/contracts/abis/veogv.json new file mode 100644 index 000000000..45008b01e --- /dev/null +++ b/src/apps/origin-dollar/contracts/abis/veogv.json @@ -0,0 +1,419 @@ +[ + { + "inputs": [ + { "internalType": "address", "name": "ogv_", "type": "address" }, + { "internalType": "uint256", "name": "epoch_", "type": "uint256" }, + { "internalType": "uint256", "name": "minStakeDuration_", "type": "uint256" }, + { "internalType": "address", "name": "rewardsSource_", "type": "address" } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [{ "internalType": "uint256", "name": "x", "type": "uint256" }], + "name": "PRBMathUD60x18__Exp2InputTooBig", + "type": "error" + }, + { + "inputs": [{ "internalType": "uint256", "name": "x", "type": "uint256" }], + "name": "PRBMathUD60x18__LogInputTooSmall", + "type": "error" + }, + { + "inputs": [{ "internalType": "uint256", "name": "prod1", "type": "uint256" }], + "name": "PRBMath__MulDivFixedPointOverflow", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": true, "internalType": "address", "name": "owner", "type": "address" }, + { "indexed": true, "internalType": "address", "name": "spender", "type": "address" }, + { "indexed": false, "internalType": "uint256", "name": "value", "type": "uint256" } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": true, "internalType": "address", "name": "delegator", "type": "address" }, + { "indexed": true, "internalType": "address", "name": "fromDelegate", "type": "address" }, + { "indexed": true, "internalType": "address", "name": "toDelegate", "type": "address" } + ], + "name": "DelegateChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": true, "internalType": "address", "name": "delegate", "type": "address" }, + { "indexed": false, "internalType": "uint256", "name": "previousBalance", "type": "uint256" }, + { "indexed": false, "internalType": "uint256", "name": "newBalance", "type": "uint256" } + ], + "name": "DelegateVotesChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": true, "internalType": "address", "name": "user", "type": "address" }, + { "indexed": false, "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "Reward", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": true, "internalType": "address", "name": "user", "type": "address" }, + { "indexed": false, "internalType": "uint256", "name": "lockupId", "type": "uint256" }, + { "indexed": false, "internalType": "uint256", "name": "amount", "type": "uint256" }, + { "indexed": false, "internalType": "uint256", "name": "end", "type": "uint256" }, + { "indexed": false, "internalType": "uint256", "name": "points", "type": "uint256" } + ], + "name": "Stake", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": true, "internalType": "address", "name": "from", "type": "address" }, + { "indexed": true, "internalType": "address", "name": "to", "type": "address" }, + { "indexed": false, "internalType": "uint256", "name": "value", "type": "uint256" } + ], + "name": "Transfer", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": true, "internalType": "address", "name": "user", "type": "address" }, + { "indexed": false, "internalType": "uint256", "name": "lockupId", "type": "uint256" }, + { "indexed": false, "internalType": "uint256", "name": "amount", "type": "uint256" }, + { "indexed": false, "internalType": "uint256", "name": "end", "type": "uint256" }, + { "indexed": false, "internalType": "uint256", "name": "points", "type": "uint256" } + ], + "name": "Unstake", + "type": "event" + }, + { + "inputs": [], + "name": "DOMAIN_SEPARATOR", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "accRewardPerShare", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "owner", "type": "address" }, + { "internalType": "address", "name": "spender", "type": "address" } + ], + "name": "allowance", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "spender", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "approve", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "account", "type": "address" }], + "name": "balanceOf", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "account", "type": "address" }, + { "internalType": "uint32", "name": "pos", "type": "uint32" } + ], + "name": "checkpoints", + "outputs": [ + { + "components": [ + { "internalType": "uint32", "name": "fromBlock", "type": "uint32" }, + { "internalType": "uint224", "name": "votes", "type": "uint224" } + ], + "internalType": "struct ERC20Votes.Checkpoint", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { "inputs": [], "name": "collectRewards", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, + { + "inputs": [], + "name": "decimals", + "outputs": [{ "internalType": "uint8", "name": "", "type": "uint8" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "spender", "type": "address" }, + { "internalType": "uint256", "name": "subtractedValue", "type": "uint256" } + ], + "name": "decreaseAllowance", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "delegatee", "type": "address" }], + "name": "delegate", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "delegatee", "type": "address" }, + { "internalType": "uint256", "name": "nonce", "type": "uint256" }, + { "internalType": "uint256", "name": "expiry", "type": "uint256" }, + { "internalType": "uint8", "name": "v", "type": "uint8" }, + { "internalType": "bytes32", "name": "r", "type": "bytes32" }, + { "internalType": "bytes32", "name": "s", "type": "bytes32" } + ], + "name": "delegateBySig", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "account", "type": "address" }], + "name": "delegates", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "epoch", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "lockupId", "type": "uint256" }, + { "internalType": "uint256", "name": "duration", "type": "uint256" } + ], + "name": "extend", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "blockNumber", "type": "uint256" }], + "name": "getPastTotalSupply", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "account", "type": "address" }, + { "internalType": "uint256", "name": "blockNumber", "type": "uint256" } + ], + "name": "getPastVotes", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "account", "type": "address" }], + "name": "getVotes", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "spender", "type": "address" }, + { "internalType": "uint256", "name": "addedValue", "type": "uint256" } + ], + "name": "increaseAllowance", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "", "type": "address" }, + { "internalType": "uint256", "name": "", "type": "uint256" } + ], + "name": "lockups", + "outputs": [ + { "internalType": "uint128", "name": "amount", "type": "uint128" }, + { "internalType": "uint128", "name": "end", "type": "uint128" }, + { "internalType": "uint256", "name": "points", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "minStakeDuration", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [{ "internalType": "string", "name": "", "type": "string" }], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "owner", "type": "address" }], + "name": "nonces", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "account", "type": "address" }], + "name": "numCheckpoints", + "outputs": [{ "internalType": "uint32", "name": "", "type": "uint32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "ogv", + "outputs": [{ "internalType": "contract ERC20", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "owner", "type": "address" }, + { "internalType": "address", "name": "spender", "type": "address" }, + { "internalType": "uint256", "name": "value", "type": "uint256" }, + { "internalType": "uint256", "name": "deadline", "type": "uint256" }, + { "internalType": "uint8", "name": "v", "type": "uint8" }, + { "internalType": "bytes32", "name": "r", "type": "bytes32" }, + { "internalType": "bytes32", "name": "s", "type": "bytes32" } + ], + "name": "permit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "amount", "type": "uint256" }, + { "internalType": "uint256", "name": "duration", "type": "uint256" } + ], + "name": "previewPoints", + "outputs": [ + { "internalType": "uint256", "name": "", "type": "uint256" }, + { "internalType": "uint256", "name": "", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "user", "type": "address" }], + "name": "previewRewards", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "rewardDebtPerShare", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rewardsSource", + "outputs": [{ "internalType": "contract RewardsSource", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "amount", "type": "uint256" }, + { "internalType": "uint256", "name": "duration", "type": "uint256" }, + { "internalType": "address", "name": "to", "type": "address" } + ], + "name": "stake", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "amount", "type": "uint256" }, + { "internalType": "uint256", "name": "duration", "type": "uint256" } + ], + "name": "stake", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [{ "internalType": "string", "name": "", "type": "string" }], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "", "type": "address" }, + { "internalType": "uint256", "name": "", "type": "uint256" } + ], + "name": "transfer", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "", "type": "address" }, + { "internalType": "address", "name": "", "type": "address" }, + { "internalType": "uint256", "name": "", "type": "uint256" } + ], + "name": "transferFrom", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "lockupId", "type": "uint256" }], + "name": "unstake", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/src/apps/origin-dollar/contracts/abis/wousd.json b/src/apps/origin-dollar/contracts/abis/wousd.json new file mode 100644 index 000000000..592e927dd --- /dev/null +++ b/src/apps/origin-dollar/contracts/abis/wousd.json @@ -0,0 +1,327 @@ +[ + { + "inputs": [ + { "internalType": "contract ERC20", "name": "underlying_", "type": "address" }, + { "internalType": "string", "name": "name_", "type": "string" }, + { "internalType": "string", "name": "symbol_", "type": "string" } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": true, "internalType": "address", "name": "owner", "type": "address" }, + { "indexed": true, "internalType": "address", "name": "spender", "type": "address" }, + { "indexed": false, "internalType": "uint256", "name": "value", "type": "uint256" } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": true, "internalType": "address", "name": "caller", "type": "address" }, + { "indexed": true, "internalType": "address", "name": "owner", "type": "address" }, + { "indexed": false, "internalType": "uint256", "name": "assets", "type": "uint256" }, + { "indexed": false, "internalType": "uint256", "name": "shares", "type": "uint256" } + ], + "name": "Deposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": true, "internalType": "address", "name": "previousGovernor", "type": "address" }, + { "indexed": true, "internalType": "address", "name": "newGovernor", "type": "address" } + ], + "name": "GovernorshipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": true, "internalType": "address", "name": "previousGovernor", "type": "address" }, + { "indexed": true, "internalType": "address", "name": "newGovernor", "type": "address" } + ], + "name": "PendingGovernorshipTransfer", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": true, "internalType": "address", "name": "from", "type": "address" }, + { "indexed": true, "internalType": "address", "name": "to", "type": "address" }, + { "indexed": false, "internalType": "uint256", "name": "value", "type": "uint256" } + ], + "name": "Transfer", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": true, "internalType": "address", "name": "caller", "type": "address" }, + { "indexed": true, "internalType": "address", "name": "receiver", "type": "address" }, + { "indexed": true, "internalType": "address", "name": "owner", "type": "address" }, + { "indexed": false, "internalType": "uint256", "name": "assets", "type": "uint256" }, + { "indexed": false, "internalType": "uint256", "name": "shares", "type": "uint256" } + ], + "name": "Withdraw", + "type": "event" + }, + { + "inputs": [ + { "internalType": "address", "name": "owner", "type": "address" }, + { "internalType": "address", "name": "spender", "type": "address" } + ], + "name": "allowance", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "spender", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "approve", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "asset", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "account", "type": "address" }], + "name": "balanceOf", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { "inputs": [], "name": "claimGovernance", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, + { + "inputs": [{ "internalType": "uint256", "name": "shares", "type": "uint256" }], + "name": "convertToAssets", + "outputs": [{ "internalType": "uint256", "name": "assets", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "assets", "type": "uint256" }], + "name": "convertToShares", + "outputs": [{ "internalType": "uint256", "name": "shares", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [{ "internalType": "uint8", "name": "", "type": "uint8" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "spender", "type": "address" }, + { "internalType": "uint256", "name": "subtractedValue", "type": "uint256" } + ], + "name": "decreaseAllowance", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "assets", "type": "uint256" }, + { "internalType": "address", "name": "receiver", "type": "address" } + ], + "name": "deposit", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "governor", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "spender", "type": "address" }, + { "internalType": "uint256", "name": "addedValue", "type": "uint256" } + ], + "name": "increaseAllowance", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { "inputs": [], "name": "initialize", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, + { + "inputs": [], + "name": "isGovernor", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "maxDeposit", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "maxMint", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "owner", "type": "address" }], + "name": "maxRedeem", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "owner", "type": "address" }], + "name": "maxWithdraw", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "shares", "type": "uint256" }, + { "internalType": "address", "name": "receiver", "type": "address" } + ], + "name": "mint", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [{ "internalType": "string", "name": "", "type": "string" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "assets", "type": "uint256" }], + "name": "previewDeposit", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "shares", "type": "uint256" }], + "name": "previewMint", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "shares", "type": "uint256" }], + "name": "previewRedeem", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "assets", "type": "uint256" }], + "name": "previewWithdraw", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "shares", "type": "uint256" }, + { "internalType": "address", "name": "receiver", "type": "address" }, + { "internalType": "address", "name": "owner", "type": "address" } + ], + "name": "redeem", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [{ "internalType": "string", "name": "", "type": "string" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalAssets", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "recipient", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "transfer", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "sender", "type": "address" }, + { "internalType": "address", "name": "recipient", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "transferFrom", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "_newGovernor", "type": "address" }], + "name": "transferGovernance", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "asset_", "type": "address" }, + { "internalType": "uint256", "name": "amount_", "type": "uint256" } + ], + "name": "transferToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "assets", "type": "uint256" }, + { "internalType": "address", "name": "receiver", "type": "address" }, + { "internalType": "address", "name": "owner", "type": "address" } + ], + "name": "withdraw", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/src/apps/origin-dollar/contracts/ethers/Veogv.ts b/src/apps/origin-dollar/contracts/ethers/Veogv.ts new file mode 100644 index 000000000..39fc9084c --- /dev/null +++ b/src/apps/origin-dollar/contracts/ethers/Veogv.ts @@ -0,0 +1,1196 @@ +/* Autogenerated file. Do not edit manually. */ +/* tslint:disable */ +/* eslint-disable */ +import type { + BaseContract, + BigNumber, + BigNumberish, + BytesLike, + CallOverrides, + ContractTransaction, + Overrides, + PopulatedTransaction, + Signer, + utils, +} from 'ethers'; +import type { FunctionFragment, Result, EventFragment } from '@ethersproject/abi'; +import type { Listener, Provider } from '@ethersproject/providers'; +import type { TypedEventFilter, TypedEvent, TypedListener, OnEvent, PromiseOrValue } from './common'; + +export declare namespace ERC20Votes { + export type CheckpointStruct = { + fromBlock: PromiseOrValue; + votes: PromiseOrValue; + }; + + export type CheckpointStructOutput = [number, BigNumber] & { + fromBlock: number; + votes: BigNumber; + }; +} + +export interface VeogvInterface extends utils.Interface { + functions: { + 'DOMAIN_SEPARATOR()': FunctionFragment; + 'accRewardPerShare()': FunctionFragment; + 'allowance(address,address)': FunctionFragment; + 'approve(address,uint256)': FunctionFragment; + 'balanceOf(address)': FunctionFragment; + 'checkpoints(address,uint32)': FunctionFragment; + 'collectRewards()': FunctionFragment; + 'decimals()': FunctionFragment; + 'decreaseAllowance(address,uint256)': FunctionFragment; + 'delegate(address)': FunctionFragment; + 'delegateBySig(address,uint256,uint256,uint8,bytes32,bytes32)': FunctionFragment; + 'delegates(address)': FunctionFragment; + 'epoch()': FunctionFragment; + 'extend(uint256,uint256)': FunctionFragment; + 'getPastTotalSupply(uint256)': FunctionFragment; + 'getPastVotes(address,uint256)': FunctionFragment; + 'getVotes(address)': FunctionFragment; + 'increaseAllowance(address,uint256)': FunctionFragment; + 'lockups(address,uint256)': FunctionFragment; + 'minStakeDuration()': FunctionFragment; + 'name()': FunctionFragment; + 'nonces(address)': FunctionFragment; + 'numCheckpoints(address)': FunctionFragment; + 'ogv()': FunctionFragment; + 'permit(address,address,uint256,uint256,uint8,bytes32,bytes32)': FunctionFragment; + 'previewPoints(uint256,uint256)': FunctionFragment; + 'previewRewards(address)': FunctionFragment; + 'rewardDebtPerShare(address)': FunctionFragment; + 'rewardsSource()': FunctionFragment; + 'stake(uint256,uint256,address)': FunctionFragment; + 'stake(uint256,uint256)': FunctionFragment; + 'symbol()': FunctionFragment; + 'totalSupply()': FunctionFragment; + 'transfer(address,uint256)': FunctionFragment; + 'transferFrom(address,address,uint256)': FunctionFragment; + 'unstake(uint256)': FunctionFragment; + }; + + getFunction( + nameOrSignatureOrTopic: + | 'DOMAIN_SEPARATOR' + | 'accRewardPerShare' + | 'allowance' + | 'approve' + | 'balanceOf' + | 'checkpoints' + | 'collectRewards' + | 'decimals' + | 'decreaseAllowance' + | 'delegate' + | 'delegateBySig' + | 'delegates' + | 'epoch' + | 'extend' + | 'getPastTotalSupply' + | 'getPastVotes' + | 'getVotes' + | 'increaseAllowance' + | 'lockups' + | 'minStakeDuration' + | 'name' + | 'nonces' + | 'numCheckpoints' + | 'ogv' + | 'permit' + | 'previewPoints' + | 'previewRewards' + | 'rewardDebtPerShare' + | 'rewardsSource' + | 'stake(uint256,uint256,address)' + | 'stake(uint256,uint256)' + | 'symbol' + | 'totalSupply' + | 'transfer' + | 'transferFrom' + | 'unstake', + ): FunctionFragment; + + encodeFunctionData(functionFragment: 'DOMAIN_SEPARATOR', values?: undefined): string; + encodeFunctionData(functionFragment: 'accRewardPerShare', values?: undefined): string; + encodeFunctionData(functionFragment: 'allowance', values: [PromiseOrValue, PromiseOrValue]): string; + encodeFunctionData( + functionFragment: 'approve', + values: [PromiseOrValue, PromiseOrValue], + ): string; + encodeFunctionData(functionFragment: 'balanceOf', values: [PromiseOrValue]): string; + encodeFunctionData( + functionFragment: 'checkpoints', + values: [PromiseOrValue, PromiseOrValue], + ): string; + encodeFunctionData(functionFragment: 'collectRewards', values?: undefined): string; + encodeFunctionData(functionFragment: 'decimals', values?: undefined): string; + encodeFunctionData( + functionFragment: 'decreaseAllowance', + values: [PromiseOrValue, PromiseOrValue], + ): string; + encodeFunctionData(functionFragment: 'delegate', values: [PromiseOrValue]): string; + encodeFunctionData( + functionFragment: 'delegateBySig', + values: [ + PromiseOrValue, + PromiseOrValue, + PromiseOrValue, + PromiseOrValue, + PromiseOrValue, + PromiseOrValue, + ], + ): string; + encodeFunctionData(functionFragment: 'delegates', values: [PromiseOrValue]): string; + encodeFunctionData(functionFragment: 'epoch', values?: undefined): string; + encodeFunctionData( + functionFragment: 'extend', + values: [PromiseOrValue, PromiseOrValue], + ): string; + encodeFunctionData(functionFragment: 'getPastTotalSupply', values: [PromiseOrValue]): string; + encodeFunctionData( + functionFragment: 'getPastVotes', + values: [PromiseOrValue, PromiseOrValue], + ): string; + encodeFunctionData(functionFragment: 'getVotes', values: [PromiseOrValue]): string; + encodeFunctionData( + functionFragment: 'increaseAllowance', + values: [PromiseOrValue, PromiseOrValue], + ): string; + encodeFunctionData( + functionFragment: 'lockups', + values: [PromiseOrValue, PromiseOrValue], + ): string; + encodeFunctionData(functionFragment: 'minStakeDuration', values?: undefined): string; + encodeFunctionData(functionFragment: 'name', values?: undefined): string; + encodeFunctionData(functionFragment: 'nonces', values: [PromiseOrValue]): string; + encodeFunctionData(functionFragment: 'numCheckpoints', values: [PromiseOrValue]): string; + encodeFunctionData(functionFragment: 'ogv', values?: undefined): string; + encodeFunctionData( + functionFragment: 'permit', + values: [ + PromiseOrValue, + PromiseOrValue, + PromiseOrValue, + PromiseOrValue, + PromiseOrValue, + PromiseOrValue, + PromiseOrValue, + ], + ): string; + encodeFunctionData( + functionFragment: 'previewPoints', + values: [PromiseOrValue, PromiseOrValue], + ): string; + encodeFunctionData(functionFragment: 'previewRewards', values: [PromiseOrValue]): string; + encodeFunctionData(functionFragment: 'rewardDebtPerShare', values: [PromiseOrValue]): string; + encodeFunctionData(functionFragment: 'rewardsSource', values?: undefined): string; + encodeFunctionData( + functionFragment: 'stake(uint256,uint256,address)', + values: [PromiseOrValue, PromiseOrValue, PromiseOrValue], + ): string; + encodeFunctionData( + functionFragment: 'stake(uint256,uint256)', + values: [PromiseOrValue, PromiseOrValue], + ): string; + encodeFunctionData(functionFragment: 'symbol', values?: undefined): string; + encodeFunctionData(functionFragment: 'totalSupply', values?: undefined): string; + encodeFunctionData( + functionFragment: 'transfer', + values: [PromiseOrValue, PromiseOrValue], + ): string; + encodeFunctionData( + functionFragment: 'transferFrom', + values: [PromiseOrValue, PromiseOrValue, PromiseOrValue], + ): string; + encodeFunctionData(functionFragment: 'unstake', values: [PromiseOrValue]): string; + + decodeFunctionResult(functionFragment: 'DOMAIN_SEPARATOR', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'accRewardPerShare', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'allowance', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'approve', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'balanceOf', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'checkpoints', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'collectRewards', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'decimals', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'decreaseAllowance', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'delegate', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'delegateBySig', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'delegates', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'epoch', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'extend', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'getPastTotalSupply', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'getPastVotes', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'getVotes', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'increaseAllowance', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'lockups', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'minStakeDuration', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'name', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'nonces', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'numCheckpoints', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'ogv', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'permit', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'previewPoints', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'previewRewards', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'rewardDebtPerShare', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'rewardsSource', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'stake(uint256,uint256,address)', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'stake(uint256,uint256)', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'symbol', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'totalSupply', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'transfer', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'transferFrom', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'unstake', data: BytesLike): Result; + + events: { + 'Approval(address,address,uint256)': EventFragment; + 'DelegateChanged(address,address,address)': EventFragment; + 'DelegateVotesChanged(address,uint256,uint256)': EventFragment; + 'Reward(address,uint256)': EventFragment; + 'Stake(address,uint256,uint256,uint256,uint256)': EventFragment; + 'Transfer(address,address,uint256)': EventFragment; + 'Unstake(address,uint256,uint256,uint256,uint256)': EventFragment; + }; + + getEvent(nameOrSignatureOrTopic: 'Approval'): EventFragment; + getEvent(nameOrSignatureOrTopic: 'DelegateChanged'): EventFragment; + getEvent(nameOrSignatureOrTopic: 'DelegateVotesChanged'): EventFragment; + getEvent(nameOrSignatureOrTopic: 'Reward'): EventFragment; + getEvent(nameOrSignatureOrTopic: 'Stake'): EventFragment; + getEvent(nameOrSignatureOrTopic: 'Transfer'): EventFragment; + getEvent(nameOrSignatureOrTopic: 'Unstake'): EventFragment; +} + +export interface ApprovalEventObject { + owner: string; + spender: string; + value: BigNumber; +} +export type ApprovalEvent = TypedEvent<[string, string, BigNumber], ApprovalEventObject>; + +export type ApprovalEventFilter = TypedEventFilter; + +export interface DelegateChangedEventObject { + delegator: string; + fromDelegate: string; + toDelegate: string; +} +export type DelegateChangedEvent = TypedEvent<[string, string, string], DelegateChangedEventObject>; + +export type DelegateChangedEventFilter = TypedEventFilter; + +export interface DelegateVotesChangedEventObject { + delegate: string; + previousBalance: BigNumber; + newBalance: BigNumber; +} +export type DelegateVotesChangedEvent = TypedEvent<[string, BigNumber, BigNumber], DelegateVotesChangedEventObject>; + +export type DelegateVotesChangedEventFilter = TypedEventFilter; + +export interface RewardEventObject { + user: string; + amount: BigNumber; +} +export type RewardEvent = TypedEvent<[string, BigNumber], RewardEventObject>; + +export type RewardEventFilter = TypedEventFilter; + +export interface StakeEventObject { + user: string; + lockupId: BigNumber; + amount: BigNumber; + end: BigNumber; + points: BigNumber; +} +export type StakeEvent = TypedEvent<[string, BigNumber, BigNumber, BigNumber, BigNumber], StakeEventObject>; + +export type StakeEventFilter = TypedEventFilter; + +export interface TransferEventObject { + from: string; + to: string; + value: BigNumber; +} +export type TransferEvent = TypedEvent<[string, string, BigNumber], TransferEventObject>; + +export type TransferEventFilter = TypedEventFilter; + +export interface UnstakeEventObject { + user: string; + lockupId: BigNumber; + amount: BigNumber; + end: BigNumber; + points: BigNumber; +} +export type UnstakeEvent = TypedEvent<[string, BigNumber, BigNumber, BigNumber, BigNumber], UnstakeEventObject>; + +export type UnstakeEventFilter = TypedEventFilter; + +export interface Veogv extends BaseContract { + connect(signerOrProvider: Signer | Provider | string): this; + attach(addressOrName: string): this; + deployed(): Promise; + + interface: VeogvInterface; + + queryFilter( + event: TypedEventFilter, + fromBlockOrBlockhash?: string | number | undefined, + toBlock?: string | number | undefined, + ): Promise>; + + listeners(eventFilter?: TypedEventFilter): Array>; + listeners(eventName?: string): Array; + removeAllListeners(eventFilter: TypedEventFilter): this; + removeAllListeners(eventName?: string): this; + off: OnEvent; + on: OnEvent; + once: OnEvent; + removeListener: OnEvent; + + functions: { + DOMAIN_SEPARATOR(overrides?: CallOverrides): Promise<[string]>; + + accRewardPerShare(overrides?: CallOverrides): Promise<[BigNumber]>; + + allowance( + owner: PromiseOrValue, + spender: PromiseOrValue, + overrides?: CallOverrides, + ): Promise<[BigNumber]>; + + approve( + spender: PromiseOrValue, + amount: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + balanceOf(account: PromiseOrValue, overrides?: CallOverrides): Promise<[BigNumber]>; + + checkpoints( + account: PromiseOrValue, + pos: PromiseOrValue, + overrides?: CallOverrides, + ): Promise<[ERC20Votes.CheckpointStructOutput]>; + + collectRewards(overrides?: Overrides & { from?: PromiseOrValue }): Promise; + + decimals(overrides?: CallOverrides): Promise<[number]>; + + decreaseAllowance( + spender: PromiseOrValue, + subtractedValue: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + delegate( + delegatee: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + delegateBySig( + delegatee: PromiseOrValue, + nonce: PromiseOrValue, + expiry: PromiseOrValue, + v: PromiseOrValue, + r: PromiseOrValue, + s: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + delegates(account: PromiseOrValue, overrides?: CallOverrides): Promise<[string]>; + + epoch(overrides?: CallOverrides): Promise<[BigNumber]>; + + extend( + lockupId: PromiseOrValue, + duration: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + getPastTotalSupply(blockNumber: PromiseOrValue, overrides?: CallOverrides): Promise<[BigNumber]>; + + getPastVotes( + account: PromiseOrValue, + blockNumber: PromiseOrValue, + overrides?: CallOverrides, + ): Promise<[BigNumber]>; + + getVotes(account: PromiseOrValue, overrides?: CallOverrides): Promise<[BigNumber]>; + + increaseAllowance( + spender: PromiseOrValue, + addedValue: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + lockups( + arg0: PromiseOrValue, + arg1: PromiseOrValue, + overrides?: CallOverrides, + ): Promise< + [BigNumber, BigNumber, BigNumber] & { + amount: BigNumber; + end: BigNumber; + points: BigNumber; + } + >; + + minStakeDuration(overrides?: CallOverrides): Promise<[BigNumber]>; + + name(overrides?: CallOverrides): Promise<[string]>; + + nonces(owner: PromiseOrValue, overrides?: CallOverrides): Promise<[BigNumber]>; + + numCheckpoints(account: PromiseOrValue, overrides?: CallOverrides): Promise<[number]>; + + ogv(overrides?: CallOverrides): Promise<[string]>; + + permit( + owner: PromiseOrValue, + spender: PromiseOrValue, + value: PromiseOrValue, + deadline: PromiseOrValue, + v: PromiseOrValue, + r: PromiseOrValue, + s: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + previewPoints( + amount: PromiseOrValue, + duration: PromiseOrValue, + overrides?: CallOverrides, + ): Promise<[BigNumber, BigNumber]>; + + previewRewards(user: PromiseOrValue, overrides?: CallOverrides): Promise<[BigNumber]>; + + rewardDebtPerShare(arg0: PromiseOrValue, overrides?: CallOverrides): Promise<[BigNumber]>; + + rewardsSource(overrides?: CallOverrides): Promise<[string]>; + + 'stake(uint256,uint256,address)'( + amount: PromiseOrValue, + duration: PromiseOrValue, + to: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + 'stake(uint256,uint256)'( + amount: PromiseOrValue, + duration: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + symbol(overrides?: CallOverrides): Promise<[string]>; + + totalSupply(overrides?: CallOverrides): Promise<[BigNumber]>; + + transfer( + arg0: PromiseOrValue, + arg1: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + transferFrom( + arg0: PromiseOrValue, + arg1: PromiseOrValue, + arg2: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + unstake( + lockupId: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + }; + + DOMAIN_SEPARATOR(overrides?: CallOverrides): Promise; + + accRewardPerShare(overrides?: CallOverrides): Promise; + + allowance( + owner: PromiseOrValue, + spender: PromiseOrValue, + overrides?: CallOverrides, + ): Promise; + + approve( + spender: PromiseOrValue, + amount: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + balanceOf(account: PromiseOrValue, overrides?: CallOverrides): Promise; + + checkpoints( + account: PromiseOrValue, + pos: PromiseOrValue, + overrides?: CallOverrides, + ): Promise; + + collectRewards(overrides?: Overrides & { from?: PromiseOrValue }): Promise; + + decimals(overrides?: CallOverrides): Promise; + + decreaseAllowance( + spender: PromiseOrValue, + subtractedValue: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + delegate( + delegatee: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + delegateBySig( + delegatee: PromiseOrValue, + nonce: PromiseOrValue, + expiry: PromiseOrValue, + v: PromiseOrValue, + r: PromiseOrValue, + s: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + delegates(account: PromiseOrValue, overrides?: CallOverrides): Promise; + + epoch(overrides?: CallOverrides): Promise; + + extend( + lockupId: PromiseOrValue, + duration: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + getPastTotalSupply(blockNumber: PromiseOrValue, overrides?: CallOverrides): Promise; + + getPastVotes( + account: PromiseOrValue, + blockNumber: PromiseOrValue, + overrides?: CallOverrides, + ): Promise; + + getVotes(account: PromiseOrValue, overrides?: CallOverrides): Promise; + + increaseAllowance( + spender: PromiseOrValue, + addedValue: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + lockups( + arg0: PromiseOrValue, + arg1: PromiseOrValue, + overrides?: CallOverrides, + ): Promise< + [BigNumber, BigNumber, BigNumber] & { + amount: BigNumber; + end: BigNumber; + points: BigNumber; + } + >; + + minStakeDuration(overrides?: CallOverrides): Promise; + + name(overrides?: CallOverrides): Promise; + + nonces(owner: PromiseOrValue, overrides?: CallOverrides): Promise; + + numCheckpoints(account: PromiseOrValue, overrides?: CallOverrides): Promise; + + ogv(overrides?: CallOverrides): Promise; + + permit( + owner: PromiseOrValue, + spender: PromiseOrValue, + value: PromiseOrValue, + deadline: PromiseOrValue, + v: PromiseOrValue, + r: PromiseOrValue, + s: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + previewPoints( + amount: PromiseOrValue, + duration: PromiseOrValue, + overrides?: CallOverrides, + ): Promise<[BigNumber, BigNumber]>; + + previewRewards(user: PromiseOrValue, overrides?: CallOverrides): Promise; + + rewardDebtPerShare(arg0: PromiseOrValue, overrides?: CallOverrides): Promise; + + rewardsSource(overrides?: CallOverrides): Promise; + + 'stake(uint256,uint256,address)'( + amount: PromiseOrValue, + duration: PromiseOrValue, + to: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + 'stake(uint256,uint256)'( + amount: PromiseOrValue, + duration: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + symbol(overrides?: CallOverrides): Promise; + + totalSupply(overrides?: CallOverrides): Promise; + + transfer( + arg0: PromiseOrValue, + arg1: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + transferFrom( + arg0: PromiseOrValue, + arg1: PromiseOrValue, + arg2: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + unstake( + lockupId: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + callStatic: { + DOMAIN_SEPARATOR(overrides?: CallOverrides): Promise; + + accRewardPerShare(overrides?: CallOverrides): Promise; + + allowance( + owner: PromiseOrValue, + spender: PromiseOrValue, + overrides?: CallOverrides, + ): Promise; + + approve( + spender: PromiseOrValue, + amount: PromiseOrValue, + overrides?: CallOverrides, + ): Promise; + + balanceOf(account: PromiseOrValue, overrides?: CallOverrides): Promise; + + checkpoints( + account: PromiseOrValue, + pos: PromiseOrValue, + overrides?: CallOverrides, + ): Promise; + + collectRewards(overrides?: CallOverrides): Promise; + + decimals(overrides?: CallOverrides): Promise; + + decreaseAllowance( + spender: PromiseOrValue, + subtractedValue: PromiseOrValue, + overrides?: CallOverrides, + ): Promise; + + delegate(delegatee: PromiseOrValue, overrides?: CallOverrides): Promise; + + delegateBySig( + delegatee: PromiseOrValue, + nonce: PromiseOrValue, + expiry: PromiseOrValue, + v: PromiseOrValue, + r: PromiseOrValue, + s: PromiseOrValue, + overrides?: CallOverrides, + ): Promise; + + delegates(account: PromiseOrValue, overrides?: CallOverrides): Promise; + + epoch(overrides?: CallOverrides): Promise; + + extend( + lockupId: PromiseOrValue, + duration: PromiseOrValue, + overrides?: CallOverrides, + ): Promise; + + getPastTotalSupply(blockNumber: PromiseOrValue, overrides?: CallOverrides): Promise; + + getPastVotes( + account: PromiseOrValue, + blockNumber: PromiseOrValue, + overrides?: CallOverrides, + ): Promise; + + getVotes(account: PromiseOrValue, overrides?: CallOverrides): Promise; + + increaseAllowance( + spender: PromiseOrValue, + addedValue: PromiseOrValue, + overrides?: CallOverrides, + ): Promise; + + lockups( + arg0: PromiseOrValue, + arg1: PromiseOrValue, + overrides?: CallOverrides, + ): Promise< + [BigNumber, BigNumber, BigNumber] & { + amount: BigNumber; + end: BigNumber; + points: BigNumber; + } + >; + + minStakeDuration(overrides?: CallOverrides): Promise; + + name(overrides?: CallOverrides): Promise; + + nonces(owner: PromiseOrValue, overrides?: CallOverrides): Promise; + + numCheckpoints(account: PromiseOrValue, overrides?: CallOverrides): Promise; + + ogv(overrides?: CallOverrides): Promise; + + permit( + owner: PromiseOrValue, + spender: PromiseOrValue, + value: PromiseOrValue, + deadline: PromiseOrValue, + v: PromiseOrValue, + r: PromiseOrValue, + s: PromiseOrValue, + overrides?: CallOverrides, + ): Promise; + + previewPoints( + amount: PromiseOrValue, + duration: PromiseOrValue, + overrides?: CallOverrides, + ): Promise<[BigNumber, BigNumber]>; + + previewRewards(user: PromiseOrValue, overrides?: CallOverrides): Promise; + + rewardDebtPerShare(arg0: PromiseOrValue, overrides?: CallOverrides): Promise; + + rewardsSource(overrides?: CallOverrides): Promise; + + 'stake(uint256,uint256,address)'( + amount: PromiseOrValue, + duration: PromiseOrValue, + to: PromiseOrValue, + overrides?: CallOverrides, + ): Promise; + + 'stake(uint256,uint256)'( + amount: PromiseOrValue, + duration: PromiseOrValue, + overrides?: CallOverrides, + ): Promise; + + symbol(overrides?: CallOverrides): Promise; + + totalSupply(overrides?: CallOverrides): Promise; + + transfer( + arg0: PromiseOrValue, + arg1: PromiseOrValue, + overrides?: CallOverrides, + ): Promise; + + transferFrom( + arg0: PromiseOrValue, + arg1: PromiseOrValue, + arg2: PromiseOrValue, + overrides?: CallOverrides, + ): Promise; + + unstake(lockupId: PromiseOrValue, overrides?: CallOverrides): Promise; + }; + + filters: { + 'Approval(address,address,uint256)'( + owner?: PromiseOrValue | null, + spender?: PromiseOrValue | null, + value?: null, + ): ApprovalEventFilter; + Approval( + owner?: PromiseOrValue | null, + spender?: PromiseOrValue | null, + value?: null, + ): ApprovalEventFilter; + + 'DelegateChanged(address,address,address)'( + delegator?: PromiseOrValue | null, + fromDelegate?: PromiseOrValue | null, + toDelegate?: PromiseOrValue | null, + ): DelegateChangedEventFilter; + DelegateChanged( + delegator?: PromiseOrValue | null, + fromDelegate?: PromiseOrValue | null, + toDelegate?: PromiseOrValue | null, + ): DelegateChangedEventFilter; + + 'DelegateVotesChanged(address,uint256,uint256)'( + delegate?: PromiseOrValue | null, + previousBalance?: null, + newBalance?: null, + ): DelegateVotesChangedEventFilter; + DelegateVotesChanged( + delegate?: PromiseOrValue | null, + previousBalance?: null, + newBalance?: null, + ): DelegateVotesChangedEventFilter; + + 'Reward(address,uint256)'(user?: PromiseOrValue | null, amount?: null): RewardEventFilter; + Reward(user?: PromiseOrValue | null, amount?: null): RewardEventFilter; + + 'Stake(address,uint256,uint256,uint256,uint256)'( + user?: PromiseOrValue | null, + lockupId?: null, + amount?: null, + end?: null, + points?: null, + ): StakeEventFilter; + Stake( + user?: PromiseOrValue | null, + lockupId?: null, + amount?: null, + end?: null, + points?: null, + ): StakeEventFilter; + + 'Transfer(address,address,uint256)'( + from?: PromiseOrValue | null, + to?: PromiseOrValue | null, + value?: null, + ): TransferEventFilter; + Transfer( + from?: PromiseOrValue | null, + to?: PromiseOrValue | null, + value?: null, + ): TransferEventFilter; + + 'Unstake(address,uint256,uint256,uint256,uint256)'( + user?: PromiseOrValue | null, + lockupId?: null, + amount?: null, + end?: null, + points?: null, + ): UnstakeEventFilter; + Unstake( + user?: PromiseOrValue | null, + lockupId?: null, + amount?: null, + end?: null, + points?: null, + ): UnstakeEventFilter; + }; + + estimateGas: { + DOMAIN_SEPARATOR(overrides?: CallOverrides): Promise; + + accRewardPerShare(overrides?: CallOverrides): Promise; + + allowance( + owner: PromiseOrValue, + spender: PromiseOrValue, + overrides?: CallOverrides, + ): Promise; + + approve( + spender: PromiseOrValue, + amount: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + balanceOf(account: PromiseOrValue, overrides?: CallOverrides): Promise; + + checkpoints( + account: PromiseOrValue, + pos: PromiseOrValue, + overrides?: CallOverrides, + ): Promise; + + collectRewards(overrides?: Overrides & { from?: PromiseOrValue }): Promise; + + decimals(overrides?: CallOverrides): Promise; + + decreaseAllowance( + spender: PromiseOrValue, + subtractedValue: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + delegate( + delegatee: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + delegateBySig( + delegatee: PromiseOrValue, + nonce: PromiseOrValue, + expiry: PromiseOrValue, + v: PromiseOrValue, + r: PromiseOrValue, + s: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + delegates(account: PromiseOrValue, overrides?: CallOverrides): Promise; + + epoch(overrides?: CallOverrides): Promise; + + extend( + lockupId: PromiseOrValue, + duration: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + getPastTotalSupply(blockNumber: PromiseOrValue, overrides?: CallOverrides): Promise; + + getPastVotes( + account: PromiseOrValue, + blockNumber: PromiseOrValue, + overrides?: CallOverrides, + ): Promise; + + getVotes(account: PromiseOrValue, overrides?: CallOverrides): Promise; + + increaseAllowance( + spender: PromiseOrValue, + addedValue: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + lockups( + arg0: PromiseOrValue, + arg1: PromiseOrValue, + overrides?: CallOverrides, + ): Promise; + + minStakeDuration(overrides?: CallOverrides): Promise; + + name(overrides?: CallOverrides): Promise; + + nonces(owner: PromiseOrValue, overrides?: CallOverrides): Promise; + + numCheckpoints(account: PromiseOrValue, overrides?: CallOverrides): Promise; + + ogv(overrides?: CallOverrides): Promise; + + permit( + owner: PromiseOrValue, + spender: PromiseOrValue, + value: PromiseOrValue, + deadline: PromiseOrValue, + v: PromiseOrValue, + r: PromiseOrValue, + s: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + previewPoints( + amount: PromiseOrValue, + duration: PromiseOrValue, + overrides?: CallOverrides, + ): Promise; + + previewRewards(user: PromiseOrValue, overrides?: CallOverrides): Promise; + + rewardDebtPerShare(arg0: PromiseOrValue, overrides?: CallOverrides): Promise; + + rewardsSource(overrides?: CallOverrides): Promise; + + 'stake(uint256,uint256,address)'( + amount: PromiseOrValue, + duration: PromiseOrValue, + to: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + 'stake(uint256,uint256)'( + amount: PromiseOrValue, + duration: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + symbol(overrides?: CallOverrides): Promise; + + totalSupply(overrides?: CallOverrides): Promise; + + transfer( + arg0: PromiseOrValue, + arg1: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + transferFrom( + arg0: PromiseOrValue, + arg1: PromiseOrValue, + arg2: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + unstake( + lockupId: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + }; + + populateTransaction: { + DOMAIN_SEPARATOR(overrides?: CallOverrides): Promise; + + accRewardPerShare(overrides?: CallOverrides): Promise; + + allowance( + owner: PromiseOrValue, + spender: PromiseOrValue, + overrides?: CallOverrides, + ): Promise; + + approve( + spender: PromiseOrValue, + amount: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + balanceOf(account: PromiseOrValue, overrides?: CallOverrides): Promise; + + checkpoints( + account: PromiseOrValue, + pos: PromiseOrValue, + overrides?: CallOverrides, + ): Promise; + + collectRewards(overrides?: Overrides & { from?: PromiseOrValue }): Promise; + + decimals(overrides?: CallOverrides): Promise; + + decreaseAllowance( + spender: PromiseOrValue, + subtractedValue: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + delegate( + delegatee: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + delegateBySig( + delegatee: PromiseOrValue, + nonce: PromiseOrValue, + expiry: PromiseOrValue, + v: PromiseOrValue, + r: PromiseOrValue, + s: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + delegates(account: PromiseOrValue, overrides?: CallOverrides): Promise; + + epoch(overrides?: CallOverrides): Promise; + + extend( + lockupId: PromiseOrValue, + duration: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + getPastTotalSupply( + blockNumber: PromiseOrValue, + overrides?: CallOverrides, + ): Promise; + + getPastVotes( + account: PromiseOrValue, + blockNumber: PromiseOrValue, + overrides?: CallOverrides, + ): Promise; + + getVotes(account: PromiseOrValue, overrides?: CallOverrides): Promise; + + increaseAllowance( + spender: PromiseOrValue, + addedValue: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + lockups( + arg0: PromiseOrValue, + arg1: PromiseOrValue, + overrides?: CallOverrides, + ): Promise; + + minStakeDuration(overrides?: CallOverrides): Promise; + + name(overrides?: CallOverrides): Promise; + + nonces(owner: PromiseOrValue, overrides?: CallOverrides): Promise; + + numCheckpoints(account: PromiseOrValue, overrides?: CallOverrides): Promise; + + ogv(overrides?: CallOverrides): Promise; + + permit( + owner: PromiseOrValue, + spender: PromiseOrValue, + value: PromiseOrValue, + deadline: PromiseOrValue, + v: PromiseOrValue, + r: PromiseOrValue, + s: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + previewPoints( + amount: PromiseOrValue, + duration: PromiseOrValue, + overrides?: CallOverrides, + ): Promise; + + previewRewards(user: PromiseOrValue, overrides?: CallOverrides): Promise; + + rewardDebtPerShare(arg0: PromiseOrValue, overrides?: CallOverrides): Promise; + + rewardsSource(overrides?: CallOverrides): Promise; + + 'stake(uint256,uint256,address)'( + amount: PromiseOrValue, + duration: PromiseOrValue, + to: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + 'stake(uint256,uint256)'( + amount: PromiseOrValue, + duration: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + symbol(overrides?: CallOverrides): Promise; + + totalSupply(overrides?: CallOverrides): Promise; + + transfer( + arg0: PromiseOrValue, + arg1: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + transferFrom( + arg0: PromiseOrValue, + arg1: PromiseOrValue, + arg2: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + unstake( + lockupId: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + }; +} diff --git a/src/apps/origin-dollar/contracts/ethers/Wousd.ts b/src/apps/origin-dollar/contracts/ethers/Wousd.ts new file mode 100644 index 000000000..4f1421a81 --- /dev/null +++ b/src/apps/origin-dollar/contracts/ethers/Wousd.ts @@ -0,0 +1,943 @@ +/* Autogenerated file. Do not edit manually. */ +/* tslint:disable */ +/* eslint-disable */ +import type { + BaseContract, + BigNumber, + BigNumberish, + BytesLike, + CallOverrides, + ContractTransaction, + Overrides, + PopulatedTransaction, + Signer, + utils, +} from 'ethers'; +import type { FunctionFragment, Result, EventFragment } from '@ethersproject/abi'; +import type { Listener, Provider } from '@ethersproject/providers'; +import type { TypedEventFilter, TypedEvent, TypedListener, OnEvent, PromiseOrValue } from './common'; + +export interface WousdInterface extends utils.Interface { + functions: { + 'allowance(address,address)': FunctionFragment; + 'approve(address,uint256)': FunctionFragment; + 'asset()': FunctionFragment; + 'balanceOf(address)': FunctionFragment; + 'claimGovernance()': FunctionFragment; + 'convertToAssets(uint256)': FunctionFragment; + 'convertToShares(uint256)': FunctionFragment; + 'decimals()': FunctionFragment; + 'decreaseAllowance(address,uint256)': FunctionFragment; + 'deposit(uint256,address)': FunctionFragment; + 'governor()': FunctionFragment; + 'increaseAllowance(address,uint256)': FunctionFragment; + 'initialize()': FunctionFragment; + 'isGovernor()': FunctionFragment; + 'maxDeposit(address)': FunctionFragment; + 'maxMint(address)': FunctionFragment; + 'maxRedeem(address)': FunctionFragment; + 'maxWithdraw(address)': FunctionFragment; + 'mint(uint256,address)': FunctionFragment; + 'name()': FunctionFragment; + 'previewDeposit(uint256)': FunctionFragment; + 'previewMint(uint256)': FunctionFragment; + 'previewRedeem(uint256)': FunctionFragment; + 'previewWithdraw(uint256)': FunctionFragment; + 'redeem(uint256,address,address)': FunctionFragment; + 'symbol()': FunctionFragment; + 'totalAssets()': FunctionFragment; + 'totalSupply()': FunctionFragment; + 'transfer(address,uint256)': FunctionFragment; + 'transferFrom(address,address,uint256)': FunctionFragment; + 'transferGovernance(address)': FunctionFragment; + 'transferToken(address,uint256)': FunctionFragment; + 'withdraw(uint256,address,address)': FunctionFragment; + }; + + getFunction( + nameOrSignatureOrTopic: + | 'allowance' + | 'approve' + | 'asset' + | 'balanceOf' + | 'claimGovernance' + | 'convertToAssets' + | 'convertToShares' + | 'decimals' + | 'decreaseAllowance' + | 'deposit' + | 'governor' + | 'increaseAllowance' + | 'initialize' + | 'isGovernor' + | 'maxDeposit' + | 'maxMint' + | 'maxRedeem' + | 'maxWithdraw' + | 'mint' + | 'name' + | 'previewDeposit' + | 'previewMint' + | 'previewRedeem' + | 'previewWithdraw' + | 'redeem' + | 'symbol' + | 'totalAssets' + | 'totalSupply' + | 'transfer' + | 'transferFrom' + | 'transferGovernance' + | 'transferToken' + | 'withdraw', + ): FunctionFragment; + + encodeFunctionData(functionFragment: 'allowance', values: [PromiseOrValue, PromiseOrValue]): string; + encodeFunctionData( + functionFragment: 'approve', + values: [PromiseOrValue, PromiseOrValue], + ): string; + encodeFunctionData(functionFragment: 'asset', values?: undefined): string; + encodeFunctionData(functionFragment: 'balanceOf', values: [PromiseOrValue]): string; + encodeFunctionData(functionFragment: 'claimGovernance', values?: undefined): string; + encodeFunctionData(functionFragment: 'convertToAssets', values: [PromiseOrValue]): string; + encodeFunctionData(functionFragment: 'convertToShares', values: [PromiseOrValue]): string; + encodeFunctionData(functionFragment: 'decimals', values?: undefined): string; + encodeFunctionData( + functionFragment: 'decreaseAllowance', + values: [PromiseOrValue, PromiseOrValue], + ): string; + encodeFunctionData( + functionFragment: 'deposit', + values: [PromiseOrValue, PromiseOrValue], + ): string; + encodeFunctionData(functionFragment: 'governor', values?: undefined): string; + encodeFunctionData( + functionFragment: 'increaseAllowance', + values: [PromiseOrValue, PromiseOrValue], + ): string; + encodeFunctionData(functionFragment: 'initialize', values?: undefined): string; + encodeFunctionData(functionFragment: 'isGovernor', values?: undefined): string; + encodeFunctionData(functionFragment: 'maxDeposit', values: [PromiseOrValue]): string; + encodeFunctionData(functionFragment: 'maxMint', values: [PromiseOrValue]): string; + encodeFunctionData(functionFragment: 'maxRedeem', values: [PromiseOrValue]): string; + encodeFunctionData(functionFragment: 'maxWithdraw', values: [PromiseOrValue]): string; + encodeFunctionData(functionFragment: 'mint', values: [PromiseOrValue, PromiseOrValue]): string; + encodeFunctionData(functionFragment: 'name', values?: undefined): string; + encodeFunctionData(functionFragment: 'previewDeposit', values: [PromiseOrValue]): string; + encodeFunctionData(functionFragment: 'previewMint', values: [PromiseOrValue]): string; + encodeFunctionData(functionFragment: 'previewRedeem', values: [PromiseOrValue]): string; + encodeFunctionData(functionFragment: 'previewWithdraw', values: [PromiseOrValue]): string; + encodeFunctionData( + functionFragment: 'redeem', + values: [PromiseOrValue, PromiseOrValue, PromiseOrValue], + ): string; + encodeFunctionData(functionFragment: 'symbol', values?: undefined): string; + encodeFunctionData(functionFragment: 'totalAssets', values?: undefined): string; + encodeFunctionData(functionFragment: 'totalSupply', values?: undefined): string; + encodeFunctionData( + functionFragment: 'transfer', + values: [PromiseOrValue, PromiseOrValue], + ): string; + encodeFunctionData( + functionFragment: 'transferFrom', + values: [PromiseOrValue, PromiseOrValue, PromiseOrValue], + ): string; + encodeFunctionData(functionFragment: 'transferGovernance', values: [PromiseOrValue]): string; + encodeFunctionData( + functionFragment: 'transferToken', + values: [PromiseOrValue, PromiseOrValue], + ): string; + encodeFunctionData( + functionFragment: 'withdraw', + values: [PromiseOrValue, PromiseOrValue, PromiseOrValue], + ): string; + + decodeFunctionResult(functionFragment: 'allowance', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'approve', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'asset', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'balanceOf', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'claimGovernance', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'convertToAssets', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'convertToShares', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'decimals', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'decreaseAllowance', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'deposit', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'governor', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'increaseAllowance', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'initialize', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'isGovernor', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'maxDeposit', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'maxMint', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'maxRedeem', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'maxWithdraw', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'mint', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'name', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'previewDeposit', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'previewMint', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'previewRedeem', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'previewWithdraw', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'redeem', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'symbol', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'totalAssets', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'totalSupply', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'transfer', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'transferFrom', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'transferGovernance', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'transferToken', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'withdraw', data: BytesLike): Result; + + events: { + 'Approval(address,address,uint256)': EventFragment; + 'Deposit(address,address,uint256,uint256)': EventFragment; + 'GovernorshipTransferred(address,address)': EventFragment; + 'PendingGovernorshipTransfer(address,address)': EventFragment; + 'Transfer(address,address,uint256)': EventFragment; + 'Withdraw(address,address,address,uint256,uint256)': EventFragment; + }; + + getEvent(nameOrSignatureOrTopic: 'Approval'): EventFragment; + getEvent(nameOrSignatureOrTopic: 'Deposit'): EventFragment; + getEvent(nameOrSignatureOrTopic: 'GovernorshipTransferred'): EventFragment; + getEvent(nameOrSignatureOrTopic: 'PendingGovernorshipTransfer'): EventFragment; + getEvent(nameOrSignatureOrTopic: 'Transfer'): EventFragment; + getEvent(nameOrSignatureOrTopic: 'Withdraw'): EventFragment; +} + +export interface ApprovalEventObject { + owner: string; + spender: string; + value: BigNumber; +} +export type ApprovalEvent = TypedEvent<[string, string, BigNumber], ApprovalEventObject>; + +export type ApprovalEventFilter = TypedEventFilter; + +export interface DepositEventObject { + caller: string; + owner: string; + assets: BigNumber; + shares: BigNumber; +} +export type DepositEvent = TypedEvent<[string, string, BigNumber, BigNumber], DepositEventObject>; + +export type DepositEventFilter = TypedEventFilter; + +export interface GovernorshipTransferredEventObject { + previousGovernor: string; + newGovernor: string; +} +export type GovernorshipTransferredEvent = TypedEvent<[string, string], GovernorshipTransferredEventObject>; + +export type GovernorshipTransferredEventFilter = TypedEventFilter; + +export interface PendingGovernorshipTransferEventObject { + previousGovernor: string; + newGovernor: string; +} +export type PendingGovernorshipTransferEvent = TypedEvent<[string, string], PendingGovernorshipTransferEventObject>; + +export type PendingGovernorshipTransferEventFilter = TypedEventFilter; + +export interface TransferEventObject { + from: string; + to: string; + value: BigNumber; +} +export type TransferEvent = TypedEvent<[string, string, BigNumber], TransferEventObject>; + +export type TransferEventFilter = TypedEventFilter; + +export interface WithdrawEventObject { + caller: string; + receiver: string; + owner: string; + assets: BigNumber; + shares: BigNumber; +} +export type WithdrawEvent = TypedEvent<[string, string, string, BigNumber, BigNumber], WithdrawEventObject>; + +export type WithdrawEventFilter = TypedEventFilter; + +export interface Wousd extends BaseContract { + connect(signerOrProvider: Signer | Provider | string): this; + attach(addressOrName: string): this; + deployed(): Promise; + + interface: WousdInterface; + + queryFilter( + event: TypedEventFilter, + fromBlockOrBlockhash?: string | number | undefined, + toBlock?: string | number | undefined, + ): Promise>; + + listeners(eventFilter?: TypedEventFilter): Array>; + listeners(eventName?: string): Array; + removeAllListeners(eventFilter: TypedEventFilter): this; + removeAllListeners(eventName?: string): this; + off: OnEvent; + on: OnEvent; + once: OnEvent; + removeListener: OnEvent; + + functions: { + allowance( + owner: PromiseOrValue, + spender: PromiseOrValue, + overrides?: CallOverrides, + ): Promise<[BigNumber]>; + + approve( + spender: PromiseOrValue, + amount: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + asset(overrides?: CallOverrides): Promise<[string]>; + + balanceOf(account: PromiseOrValue, overrides?: CallOverrides): Promise<[BigNumber]>; + + claimGovernance(overrides?: Overrides & { from?: PromiseOrValue }): Promise; + + convertToAssets( + shares: PromiseOrValue, + overrides?: CallOverrides, + ): Promise<[BigNumber] & { assets: BigNumber }>; + + convertToShares( + assets: PromiseOrValue, + overrides?: CallOverrides, + ): Promise<[BigNumber] & { shares: BigNumber }>; + + decimals(overrides?: CallOverrides): Promise<[number]>; + + decreaseAllowance( + spender: PromiseOrValue, + subtractedValue: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + deposit( + assets: PromiseOrValue, + receiver: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + governor(overrides?: CallOverrides): Promise<[string]>; + + increaseAllowance( + spender: PromiseOrValue, + addedValue: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + initialize(overrides?: Overrides & { from?: PromiseOrValue }): Promise; + + isGovernor(overrides?: CallOverrides): Promise<[boolean]>; + + maxDeposit(arg0: PromiseOrValue, overrides?: CallOverrides): Promise<[BigNumber]>; + + maxMint(arg0: PromiseOrValue, overrides?: CallOverrides): Promise<[BigNumber]>; + + maxRedeem(owner: PromiseOrValue, overrides?: CallOverrides): Promise<[BigNumber]>; + + maxWithdraw(owner: PromiseOrValue, overrides?: CallOverrides): Promise<[BigNumber]>; + + mint( + shares: PromiseOrValue, + receiver: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + name(overrides?: CallOverrides): Promise<[string]>; + + previewDeposit(assets: PromiseOrValue, overrides?: CallOverrides): Promise<[BigNumber]>; + + previewMint(shares: PromiseOrValue, overrides?: CallOverrides): Promise<[BigNumber]>; + + previewRedeem(shares: PromiseOrValue, overrides?: CallOverrides): Promise<[BigNumber]>; + + previewWithdraw(assets: PromiseOrValue, overrides?: CallOverrides): Promise<[BigNumber]>; + + redeem( + shares: PromiseOrValue, + receiver: PromiseOrValue, + owner: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + symbol(overrides?: CallOverrides): Promise<[string]>; + + totalAssets(overrides?: CallOverrides): Promise<[BigNumber]>; + + totalSupply(overrides?: CallOverrides): Promise<[BigNumber]>; + + transfer( + recipient: PromiseOrValue, + amount: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + transferFrom( + sender: PromiseOrValue, + recipient: PromiseOrValue, + amount: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + transferGovernance( + _newGovernor: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + transferToken( + asset_: PromiseOrValue, + amount_: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + withdraw( + assets: PromiseOrValue, + receiver: PromiseOrValue, + owner: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + }; + + allowance( + owner: PromiseOrValue, + spender: PromiseOrValue, + overrides?: CallOverrides, + ): Promise; + + approve( + spender: PromiseOrValue, + amount: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + asset(overrides?: CallOverrides): Promise; + + balanceOf(account: PromiseOrValue, overrides?: CallOverrides): Promise; + + claimGovernance(overrides?: Overrides & { from?: PromiseOrValue }): Promise; + + convertToAssets(shares: PromiseOrValue, overrides?: CallOverrides): Promise; + + convertToShares(assets: PromiseOrValue, overrides?: CallOverrides): Promise; + + decimals(overrides?: CallOverrides): Promise; + + decreaseAllowance( + spender: PromiseOrValue, + subtractedValue: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + deposit( + assets: PromiseOrValue, + receiver: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + governor(overrides?: CallOverrides): Promise; + + increaseAllowance( + spender: PromiseOrValue, + addedValue: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + initialize(overrides?: Overrides & { from?: PromiseOrValue }): Promise; + + isGovernor(overrides?: CallOverrides): Promise; + + maxDeposit(arg0: PromiseOrValue, overrides?: CallOverrides): Promise; + + maxMint(arg0: PromiseOrValue, overrides?: CallOverrides): Promise; + + maxRedeem(owner: PromiseOrValue, overrides?: CallOverrides): Promise; + + maxWithdraw(owner: PromiseOrValue, overrides?: CallOverrides): Promise; + + mint( + shares: PromiseOrValue, + receiver: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + name(overrides?: CallOverrides): Promise; + + previewDeposit(assets: PromiseOrValue, overrides?: CallOverrides): Promise; + + previewMint(shares: PromiseOrValue, overrides?: CallOverrides): Promise; + + previewRedeem(shares: PromiseOrValue, overrides?: CallOverrides): Promise; + + previewWithdraw(assets: PromiseOrValue, overrides?: CallOverrides): Promise; + + redeem( + shares: PromiseOrValue, + receiver: PromiseOrValue, + owner: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + symbol(overrides?: CallOverrides): Promise; + + totalAssets(overrides?: CallOverrides): Promise; + + totalSupply(overrides?: CallOverrides): Promise; + + transfer( + recipient: PromiseOrValue, + amount: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + transferFrom( + sender: PromiseOrValue, + recipient: PromiseOrValue, + amount: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + transferGovernance( + _newGovernor: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + transferToken( + asset_: PromiseOrValue, + amount_: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + withdraw( + assets: PromiseOrValue, + receiver: PromiseOrValue, + owner: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + callStatic: { + allowance( + owner: PromiseOrValue, + spender: PromiseOrValue, + overrides?: CallOverrides, + ): Promise; + + approve( + spender: PromiseOrValue, + amount: PromiseOrValue, + overrides?: CallOverrides, + ): Promise; + + asset(overrides?: CallOverrides): Promise; + + balanceOf(account: PromiseOrValue, overrides?: CallOverrides): Promise; + + claimGovernance(overrides?: CallOverrides): Promise; + + convertToAssets(shares: PromiseOrValue, overrides?: CallOverrides): Promise; + + convertToShares(assets: PromiseOrValue, overrides?: CallOverrides): Promise; + + decimals(overrides?: CallOverrides): Promise; + + decreaseAllowance( + spender: PromiseOrValue, + subtractedValue: PromiseOrValue, + overrides?: CallOverrides, + ): Promise; + + deposit( + assets: PromiseOrValue, + receiver: PromiseOrValue, + overrides?: CallOverrides, + ): Promise; + + governor(overrides?: CallOverrides): Promise; + + increaseAllowance( + spender: PromiseOrValue, + addedValue: PromiseOrValue, + overrides?: CallOverrides, + ): Promise; + + initialize(overrides?: CallOverrides): Promise; + + isGovernor(overrides?: CallOverrides): Promise; + + maxDeposit(arg0: PromiseOrValue, overrides?: CallOverrides): Promise; + + maxMint(arg0: PromiseOrValue, overrides?: CallOverrides): Promise; + + maxRedeem(owner: PromiseOrValue, overrides?: CallOverrides): Promise; + + maxWithdraw(owner: PromiseOrValue, overrides?: CallOverrides): Promise; + + mint( + shares: PromiseOrValue, + receiver: PromiseOrValue, + overrides?: CallOverrides, + ): Promise; + + name(overrides?: CallOverrides): Promise; + + previewDeposit(assets: PromiseOrValue, overrides?: CallOverrides): Promise; + + previewMint(shares: PromiseOrValue, overrides?: CallOverrides): Promise; + + previewRedeem(shares: PromiseOrValue, overrides?: CallOverrides): Promise; + + previewWithdraw(assets: PromiseOrValue, overrides?: CallOverrides): Promise; + + redeem( + shares: PromiseOrValue, + receiver: PromiseOrValue, + owner: PromiseOrValue, + overrides?: CallOverrides, + ): Promise; + + symbol(overrides?: CallOverrides): Promise; + + totalAssets(overrides?: CallOverrides): Promise; + + totalSupply(overrides?: CallOverrides): Promise; + + transfer( + recipient: PromiseOrValue, + amount: PromiseOrValue, + overrides?: CallOverrides, + ): Promise; + + transferFrom( + sender: PromiseOrValue, + recipient: PromiseOrValue, + amount: PromiseOrValue, + overrides?: CallOverrides, + ): Promise; + + transferGovernance(_newGovernor: PromiseOrValue, overrides?: CallOverrides): Promise; + + transferToken( + asset_: PromiseOrValue, + amount_: PromiseOrValue, + overrides?: CallOverrides, + ): Promise; + + withdraw( + assets: PromiseOrValue, + receiver: PromiseOrValue, + owner: PromiseOrValue, + overrides?: CallOverrides, + ): Promise; + }; + + filters: { + 'Approval(address,address,uint256)'( + owner?: PromiseOrValue | null, + spender?: PromiseOrValue | null, + value?: null, + ): ApprovalEventFilter; + Approval( + owner?: PromiseOrValue | null, + spender?: PromiseOrValue | null, + value?: null, + ): ApprovalEventFilter; + + 'Deposit(address,address,uint256,uint256)'( + caller?: PromiseOrValue | null, + owner?: PromiseOrValue | null, + assets?: null, + shares?: null, + ): DepositEventFilter; + Deposit( + caller?: PromiseOrValue | null, + owner?: PromiseOrValue | null, + assets?: null, + shares?: null, + ): DepositEventFilter; + + 'GovernorshipTransferred(address,address)'( + previousGovernor?: PromiseOrValue | null, + newGovernor?: PromiseOrValue | null, + ): GovernorshipTransferredEventFilter; + GovernorshipTransferred( + previousGovernor?: PromiseOrValue | null, + newGovernor?: PromiseOrValue | null, + ): GovernorshipTransferredEventFilter; + + 'PendingGovernorshipTransfer(address,address)'( + previousGovernor?: PromiseOrValue | null, + newGovernor?: PromiseOrValue | null, + ): PendingGovernorshipTransferEventFilter; + PendingGovernorshipTransfer( + previousGovernor?: PromiseOrValue | null, + newGovernor?: PromiseOrValue | null, + ): PendingGovernorshipTransferEventFilter; + + 'Transfer(address,address,uint256)'( + from?: PromiseOrValue | null, + to?: PromiseOrValue | null, + value?: null, + ): TransferEventFilter; + Transfer( + from?: PromiseOrValue | null, + to?: PromiseOrValue | null, + value?: null, + ): TransferEventFilter; + + 'Withdraw(address,address,address,uint256,uint256)'( + caller?: PromiseOrValue | null, + receiver?: PromiseOrValue | null, + owner?: PromiseOrValue | null, + assets?: null, + shares?: null, + ): WithdrawEventFilter; + Withdraw( + caller?: PromiseOrValue | null, + receiver?: PromiseOrValue | null, + owner?: PromiseOrValue | null, + assets?: null, + shares?: null, + ): WithdrawEventFilter; + }; + + estimateGas: { + allowance( + owner: PromiseOrValue, + spender: PromiseOrValue, + overrides?: CallOverrides, + ): Promise; + + approve( + spender: PromiseOrValue, + amount: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + asset(overrides?: CallOverrides): Promise; + + balanceOf(account: PromiseOrValue, overrides?: CallOverrides): Promise; + + claimGovernance(overrides?: Overrides & { from?: PromiseOrValue }): Promise; + + convertToAssets(shares: PromiseOrValue, overrides?: CallOverrides): Promise; + + convertToShares(assets: PromiseOrValue, overrides?: CallOverrides): Promise; + + decimals(overrides?: CallOverrides): Promise; + + decreaseAllowance( + spender: PromiseOrValue, + subtractedValue: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + deposit( + assets: PromiseOrValue, + receiver: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + governor(overrides?: CallOverrides): Promise; + + increaseAllowance( + spender: PromiseOrValue, + addedValue: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + initialize(overrides?: Overrides & { from?: PromiseOrValue }): Promise; + + isGovernor(overrides?: CallOverrides): Promise; + + maxDeposit(arg0: PromiseOrValue, overrides?: CallOverrides): Promise; + + maxMint(arg0: PromiseOrValue, overrides?: CallOverrides): Promise; + + maxRedeem(owner: PromiseOrValue, overrides?: CallOverrides): Promise; + + maxWithdraw(owner: PromiseOrValue, overrides?: CallOverrides): Promise; + + mint( + shares: PromiseOrValue, + receiver: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + name(overrides?: CallOverrides): Promise; + + previewDeposit(assets: PromiseOrValue, overrides?: CallOverrides): Promise; + + previewMint(shares: PromiseOrValue, overrides?: CallOverrides): Promise; + + previewRedeem(shares: PromiseOrValue, overrides?: CallOverrides): Promise; + + previewWithdraw(assets: PromiseOrValue, overrides?: CallOverrides): Promise; + + redeem( + shares: PromiseOrValue, + receiver: PromiseOrValue, + owner: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + symbol(overrides?: CallOverrides): Promise; + + totalAssets(overrides?: CallOverrides): Promise; + + totalSupply(overrides?: CallOverrides): Promise; + + transfer( + recipient: PromiseOrValue, + amount: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + transferFrom( + sender: PromiseOrValue, + recipient: PromiseOrValue, + amount: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + transferGovernance( + _newGovernor: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + transferToken( + asset_: PromiseOrValue, + amount_: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + withdraw( + assets: PromiseOrValue, + receiver: PromiseOrValue, + owner: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + }; + + populateTransaction: { + allowance( + owner: PromiseOrValue, + spender: PromiseOrValue, + overrides?: CallOverrides, + ): Promise; + + approve( + spender: PromiseOrValue, + amount: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + asset(overrides?: CallOverrides): Promise; + + balanceOf(account: PromiseOrValue, overrides?: CallOverrides): Promise; + + claimGovernance(overrides?: Overrides & { from?: PromiseOrValue }): Promise; + + convertToAssets(shares: PromiseOrValue, overrides?: CallOverrides): Promise; + + convertToShares(assets: PromiseOrValue, overrides?: CallOverrides): Promise; + + decimals(overrides?: CallOverrides): Promise; + + decreaseAllowance( + spender: PromiseOrValue, + subtractedValue: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + deposit( + assets: PromiseOrValue, + receiver: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + governor(overrides?: CallOverrides): Promise; + + increaseAllowance( + spender: PromiseOrValue, + addedValue: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + initialize(overrides?: Overrides & { from?: PromiseOrValue }): Promise; + + isGovernor(overrides?: CallOverrides): Promise; + + maxDeposit(arg0: PromiseOrValue, overrides?: CallOverrides): Promise; + + maxMint(arg0: PromiseOrValue, overrides?: CallOverrides): Promise; + + maxRedeem(owner: PromiseOrValue, overrides?: CallOverrides): Promise; + + maxWithdraw(owner: PromiseOrValue, overrides?: CallOverrides): Promise; + + mint( + shares: PromiseOrValue, + receiver: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + name(overrides?: CallOverrides): Promise; + + previewDeposit(assets: PromiseOrValue, overrides?: CallOverrides): Promise; + + previewMint(shares: PromiseOrValue, overrides?: CallOverrides): Promise; + + previewRedeem(shares: PromiseOrValue, overrides?: CallOverrides): Promise; + + previewWithdraw(assets: PromiseOrValue, overrides?: CallOverrides): Promise; + + redeem( + shares: PromiseOrValue, + receiver: PromiseOrValue, + owner: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + symbol(overrides?: CallOverrides): Promise; + + totalAssets(overrides?: CallOverrides): Promise; + + totalSupply(overrides?: CallOverrides): Promise; + + transfer( + recipient: PromiseOrValue, + amount: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + transferFrom( + sender: PromiseOrValue, + recipient: PromiseOrValue, + amount: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + transferGovernance( + _newGovernor: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + transferToken( + asset_: PromiseOrValue, + amount_: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + withdraw( + assets: PromiseOrValue, + receiver: PromiseOrValue, + owner: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + }; +} diff --git a/src/apps/origin-dollar/contracts/ethers/common.ts b/src/apps/origin-dollar/contracts/ethers/common.ts new file mode 100644 index 000000000..35f31be99 --- /dev/null +++ b/src/apps/origin-dollar/contracts/ethers/common.ts @@ -0,0 +1,32 @@ +/* Autogenerated file. Do not edit manually. */ +/* tslint:disable */ +/* eslint-disable */ +import type { Listener } from '@ethersproject/providers'; +import type { Event, EventFilter } from 'ethers'; + +export interface TypedEvent = any, TArgsObject = any> extends Event { + args: TArgsArray & TArgsObject; +} + +export interface TypedEventFilter<_TEvent extends TypedEvent> extends EventFilter {} + +export interface TypedListener { + (...listenerArg: [...__TypechainArgsArray, TEvent]): void; +} + +type __TypechainArgsArray = T extends TypedEvent ? U : never; + +export interface OnEvent { + (eventFilter: TypedEventFilter, listener: TypedListener): TRes; + (eventName: string, listener: Listener): TRes; +} + +export type MinEthersFactory = { + deploy(...a: ARGS[]): Promise; +}; + +export type GetContractTypeFromFactory = F extends MinEthersFactory ? C : never; + +export type GetARGsTypeFromFactory = F extends MinEthersFactory ? Parameters : never; + +export type PromiseOrValue = T | Promise; diff --git a/src/apps/origin-dollar/contracts/ethers/factories/Veogv__factory.ts b/src/apps/origin-dollar/contracts/ethers/factories/Veogv__factory.ts new file mode 100644 index 000000000..dce7f06cf --- /dev/null +++ b/src/apps/origin-dollar/contracts/ethers/factories/Veogv__factory.ts @@ -0,0 +1,999 @@ +/* Autogenerated file. Do not edit manually. */ +/* tslint:disable */ +/* eslint-disable */ + +import { Contract, Signer, utils } from 'ethers'; +import type { Provider } from '@ethersproject/providers'; +import type { Veogv, VeogvInterface } from '../Veogv'; + +const _abi = [ + { + inputs: [ + { + internalType: 'address', + name: 'ogv_', + type: 'address', + }, + { + internalType: 'uint256', + name: 'epoch_', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'minStakeDuration_', + type: 'uint256', + }, + { + internalType: 'address', + name: 'rewardsSource_', + type: 'address', + }, + ], + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + inputs: [ + { + internalType: 'uint256', + name: 'x', + type: 'uint256', + }, + ], + name: 'PRBMathUD60x18__Exp2InputTooBig', + type: 'error', + }, + { + inputs: [ + { + internalType: 'uint256', + name: 'x', + type: 'uint256', + }, + ], + name: 'PRBMathUD60x18__LogInputTooSmall', + type: 'error', + }, + { + inputs: [ + { + internalType: 'uint256', + name: 'prod1', + type: 'uint256', + }, + ], + name: 'PRBMath__MulDivFixedPointOverflow', + type: 'error', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'spender', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'value', + type: 'uint256', + }, + ], + name: 'Approval', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'delegator', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'fromDelegate', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'toDelegate', + type: 'address', + }, + ], + name: 'DelegateChanged', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'delegate', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'previousBalance', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newBalance', + type: 'uint256', + }, + ], + name: 'DelegateVotesChanged', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'user', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'Reward', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'user', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'lockupId', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'end', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'points', + type: 'uint256', + }, + ], + name: 'Stake', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'from', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'to', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'value', + type: 'uint256', + }, + ], + name: 'Transfer', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'user', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'lockupId', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'end', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'points', + type: 'uint256', + }, + ], + name: 'Unstake', + type: 'event', + }, + { + inputs: [], + name: 'DOMAIN_SEPARATOR', + outputs: [ + { + internalType: 'bytes32', + name: '', + type: 'bytes32', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'accRewardPerShare', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + internalType: 'address', + name: 'spender', + type: 'address', + }, + ], + name: 'allowance', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'spender', + type: 'address', + }, + { + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'approve', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'balanceOf', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'account', + type: 'address', + }, + { + internalType: 'uint32', + name: 'pos', + type: 'uint32', + }, + ], + name: 'checkpoints', + outputs: [ + { + components: [ + { + internalType: 'uint32', + name: 'fromBlock', + type: 'uint32', + }, + { + internalType: 'uint224', + name: 'votes', + type: 'uint224', + }, + ], + internalType: 'struct ERC20Votes.Checkpoint', + name: '', + type: 'tuple', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'collectRewards', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'decimals', + outputs: [ + { + internalType: 'uint8', + name: '', + type: 'uint8', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'spender', + type: 'address', + }, + { + internalType: 'uint256', + name: 'subtractedValue', + type: 'uint256', + }, + ], + name: 'decreaseAllowance', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'delegatee', + type: 'address', + }, + ], + name: 'delegate', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'delegatee', + type: 'address', + }, + { + internalType: 'uint256', + name: 'nonce', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'expiry', + type: 'uint256', + }, + { + internalType: 'uint8', + name: 'v', + type: 'uint8', + }, + { + internalType: 'bytes32', + name: 'r', + type: 'bytes32', + }, + { + internalType: 'bytes32', + name: 's', + type: 'bytes32', + }, + ], + name: 'delegateBySig', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'delegates', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'epoch', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: 'lockupId', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'duration', + type: 'uint256', + }, + ], + name: 'extend', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: 'blockNumber', + type: 'uint256', + }, + ], + name: 'getPastTotalSupply', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'account', + type: 'address', + }, + { + internalType: 'uint256', + name: 'blockNumber', + type: 'uint256', + }, + ], + name: 'getPastVotes', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'getVotes', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'spender', + type: 'address', + }, + { + internalType: 'uint256', + name: 'addedValue', + type: 'uint256', + }, + ], + name: 'increaseAllowance', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + name: 'lockups', + outputs: [ + { + internalType: 'uint128', + name: 'amount', + type: 'uint128', + }, + { + internalType: 'uint128', + name: 'end', + type: 'uint128', + }, + { + internalType: 'uint256', + name: 'points', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'minStakeDuration', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'name', + outputs: [ + { + internalType: 'string', + name: '', + type: 'string', + }, + ], + stateMutability: 'pure', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'owner', + type: 'address', + }, + ], + name: 'nonces', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'numCheckpoints', + outputs: [ + { + internalType: 'uint32', + name: '', + type: 'uint32', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'ogv', + outputs: [ + { + internalType: 'contract ERC20', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + internalType: 'address', + name: 'spender', + type: 'address', + }, + { + internalType: 'uint256', + name: 'value', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'deadline', + type: 'uint256', + }, + { + internalType: 'uint8', + name: 'v', + type: 'uint8', + }, + { + internalType: 'bytes32', + name: 'r', + type: 'bytes32', + }, + { + internalType: 'bytes32', + name: 's', + type: 'bytes32', + }, + ], + name: 'permit', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'duration', + type: 'uint256', + }, + ], + name: 'previewPoints', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'user', + type: 'address', + }, + ], + name: 'previewRewards', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + name: 'rewardDebtPerShare', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'rewardsSource', + outputs: [ + { + internalType: 'contract RewardsSource', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'duration', + type: 'uint256', + }, + { + internalType: 'address', + name: 'to', + type: 'address', + }, + ], + name: 'stake', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'duration', + type: 'uint256', + }, + ], + name: 'stake', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'symbol', + outputs: [ + { + internalType: 'string', + name: '', + type: 'string', + }, + ], + stateMutability: 'pure', + type: 'function', + }, + { + inputs: [], + name: 'totalSupply', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + name: 'transfer', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + { + internalType: 'address', + name: '', + type: 'address', + }, + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + name: 'transferFrom', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: 'lockupId', + type: 'uint256', + }, + ], + name: 'unstake', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, +]; + +export class Veogv__factory { + static readonly abi = _abi; + static createInterface(): VeogvInterface { + return new utils.Interface(_abi) as VeogvInterface; + } + static connect(address: string, signerOrProvider: Signer | Provider): Veogv { + return new Contract(address, _abi, signerOrProvider) as Veogv; + } +} diff --git a/src/apps/origin-dollar/contracts/ethers/factories/Wousd__factory.ts b/src/apps/origin-dollar/contracts/ethers/factories/Wousd__factory.ts new file mode 100644 index 000000000..dff067c2c --- /dev/null +++ b/src/apps/origin-dollar/contracts/ethers/factories/Wousd__factory.ts @@ -0,0 +1,810 @@ +/* Autogenerated file. Do not edit manually. */ +/* tslint:disable */ +/* eslint-disable */ + +import { Contract, Signer, utils } from 'ethers'; +import type { Provider } from '@ethersproject/providers'; +import type { Wousd, WousdInterface } from '../Wousd'; + +const _abi = [ + { + inputs: [ + { + internalType: 'contract ERC20', + name: 'underlying_', + type: 'address', + }, + { + internalType: 'string', + name: 'name_', + type: 'string', + }, + { + internalType: 'string', + name: 'symbol_', + type: 'string', + }, + ], + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'spender', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'value', + type: 'uint256', + }, + ], + name: 'Approval', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'caller', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'assets', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'shares', + type: 'uint256', + }, + ], + name: 'Deposit', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'previousGovernor', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'newGovernor', + type: 'address', + }, + ], + name: 'GovernorshipTransferred', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'previousGovernor', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'newGovernor', + type: 'address', + }, + ], + name: 'PendingGovernorshipTransfer', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'from', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'to', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'value', + type: 'uint256', + }, + ], + name: 'Transfer', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'caller', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'receiver', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'assets', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'shares', + type: 'uint256', + }, + ], + name: 'Withdraw', + type: 'event', + }, + { + inputs: [ + { + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + internalType: 'address', + name: 'spender', + type: 'address', + }, + ], + name: 'allowance', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'spender', + type: 'address', + }, + { + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'approve', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'asset', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'balanceOf', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'claimGovernance', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: 'shares', + type: 'uint256', + }, + ], + name: 'convertToAssets', + outputs: [ + { + internalType: 'uint256', + name: 'assets', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: 'assets', + type: 'uint256', + }, + ], + name: 'convertToShares', + outputs: [ + { + internalType: 'uint256', + name: 'shares', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'decimals', + outputs: [ + { + internalType: 'uint8', + name: '', + type: 'uint8', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'spender', + type: 'address', + }, + { + internalType: 'uint256', + name: 'subtractedValue', + type: 'uint256', + }, + ], + name: 'decreaseAllowance', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: 'assets', + type: 'uint256', + }, + { + internalType: 'address', + name: 'receiver', + type: 'address', + }, + ], + name: 'deposit', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'governor', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'spender', + type: 'address', + }, + { + internalType: 'uint256', + name: 'addedValue', + type: 'uint256', + }, + ], + name: 'increaseAllowance', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'initialize', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'isGovernor', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + name: 'maxDeposit', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + name: 'maxMint', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'owner', + type: 'address', + }, + ], + name: 'maxRedeem', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'owner', + type: 'address', + }, + ], + name: 'maxWithdraw', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: 'shares', + type: 'uint256', + }, + { + internalType: 'address', + name: 'receiver', + type: 'address', + }, + ], + name: 'mint', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'name', + outputs: [ + { + internalType: 'string', + name: '', + type: 'string', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: 'assets', + type: 'uint256', + }, + ], + name: 'previewDeposit', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: 'shares', + type: 'uint256', + }, + ], + name: 'previewMint', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: 'shares', + type: 'uint256', + }, + ], + name: 'previewRedeem', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: 'assets', + type: 'uint256', + }, + ], + name: 'previewWithdraw', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: 'shares', + type: 'uint256', + }, + { + internalType: 'address', + name: 'receiver', + type: 'address', + }, + { + internalType: 'address', + name: 'owner', + type: 'address', + }, + ], + name: 'redeem', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'symbol', + outputs: [ + { + internalType: 'string', + name: '', + type: 'string', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'totalAssets', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'totalSupply', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'recipient', + type: 'address', + }, + { + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'transfer', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'sender', + type: 'address', + }, + { + internalType: 'address', + name: 'recipient', + type: 'address', + }, + { + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'transferFrom', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_newGovernor', + type: 'address', + }, + ], + name: 'transferGovernance', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'asset_', + type: 'address', + }, + { + internalType: 'uint256', + name: 'amount_', + type: 'uint256', + }, + ], + name: 'transferToken', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: 'assets', + type: 'uint256', + }, + { + internalType: 'address', + name: 'receiver', + type: 'address', + }, + { + internalType: 'address', + name: 'owner', + type: 'address', + }, + ], + name: 'withdraw', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, +]; + +export class Wousd__factory { + static readonly abi = _abi; + static createInterface(): WousdInterface { + return new utils.Interface(_abi) as WousdInterface; + } + static connect(address: string, signerOrProvider: Signer | Provider): Wousd { + return new Contract(address, _abi, signerOrProvider) as Wousd; + } +} diff --git a/src/apps/origin-dollar/contracts/ethers/factories/index.ts b/src/apps/origin-dollar/contracts/ethers/factories/index.ts new file mode 100644 index 000000000..7126e6866 --- /dev/null +++ b/src/apps/origin-dollar/contracts/ethers/factories/index.ts @@ -0,0 +1,5 @@ +/* Autogenerated file. Do not edit manually. */ +/* tslint:disable */ +/* eslint-disable */ +export { Veogv__factory } from './Veogv__factory'; +export { Wousd__factory } from './Wousd__factory'; diff --git a/src/apps/origin-dollar/contracts/ethers/index.ts b/src/apps/origin-dollar/contracts/ethers/index.ts new file mode 100644 index 000000000..13e9e7153 --- /dev/null +++ b/src/apps/origin-dollar/contracts/ethers/index.ts @@ -0,0 +1,8 @@ +/* Autogenerated file. Do not edit manually. */ +/* tslint:disable */ +/* eslint-disable */ +export type { Veogv } from './Veogv'; +export type { Wousd } from './Wousd'; +export * as factories from './factories'; +export { Veogv__factory } from './factories/Veogv__factory'; +export { Wousd__factory } from './factories/Wousd__factory'; diff --git a/src/apps/origin-dollar/contracts/index.ts b/src/apps/origin-dollar/contracts/index.ts new file mode 100644 index 000000000..bedf1e93c --- /dev/null +++ b/src/apps/origin-dollar/contracts/index.ts @@ -0,0 +1,28 @@ +import { Injectable, Inject } from '@nestjs/common'; + +import { IAppToolkit, APP_TOOLKIT } from '~app-toolkit/app-toolkit.interface'; +import { ContractFactory } from '~contract/contracts'; +import { Network } from '~types/network.interface'; + +import { Veogv__factory } from './ethers'; +import { Wousd__factory } from './ethers'; + +// eslint-disable-next-line +type ContractOpts = { address: string; network: Network }; + +@Injectable() +export class OriginDollarContractFactory extends ContractFactory { + constructor(@Inject(APP_TOOLKIT) protected readonly appToolkit: IAppToolkit) { + super((network: Network) => appToolkit.getNetworkProvider(network)); + } + + veogv({ address, network }: ContractOpts) { + return Veogv__factory.connect(address, this.appToolkit.getNetworkProvider(network)); + } + wousd({ address, network }: ContractOpts) { + return Wousd__factory.connect(address, this.appToolkit.getNetworkProvider(network)); + } +} + +export type { Veogv } from './ethers'; +export type { Wousd } from './ethers'; diff --git a/src/apps/origin-dollar/ethereum/origin-dollar.balance-fetcher.ts b/src/apps/origin-dollar/ethereum/origin-dollar.balance-fetcher.ts new file mode 100644 index 000000000..ded08bc91 --- /dev/null +++ b/src/apps/origin-dollar/ethereum/origin-dollar.balance-fetcher.ts @@ -0,0 +1,64 @@ +import { Inject } from '@nestjs/common'; + +import { IAppToolkit, APP_TOOLKIT } from '~app-toolkit/app-toolkit.interface'; +import { Register } from '~app-toolkit/decorators'; +import { presentBalanceFetcherResponse } from '~app-toolkit/helpers/presentation/balance-fetcher-response.present'; +import { BalanceFetcher } from '~balance/balance-fetcher.interface'; +import { Network } from '~types/network.interface'; + +import { OGVRewardsBalanceHelper } from '../helpers/ogv-rewards.balance-helper'; +import { ORIGIN_DOLLAR_DEFINITION } from '../origin-dollar.definition'; + +const network = Network.ETHEREUM_MAINNET; + +@Register.BalanceFetcher(ORIGIN_DOLLAR_DEFINITION.id, network) +export class EthereumOriginDollarBalanceFetcher implements BalanceFetcher { + constructor( + @Inject(APP_TOOLKIT) private readonly appToolkit: IAppToolkit, + @Inject(OGVRewardsBalanceHelper) private readonly rewardsBalanceHelper: OGVRewardsBalanceHelper, + ) {} + + async getStakeBalances(address: string) { + return this.appToolkit.helpers.tokenBalanceHelper.getTokenBalances({ + address, + appId: ORIGIN_DOLLAR_DEFINITION.id, + groupId: ORIGIN_DOLLAR_DEFINITION.groups.veogv.id, + network: Network.ETHEREUM_MAINNET, + }); + } + + private async getClaimableBalances(address: string) { + return this.rewardsBalanceHelper.getClaimableBalances({ + address, + appId: ORIGIN_DOLLAR_DEFINITION.id, + groupId: ORIGIN_DOLLAR_DEFINITION.groups.rewards.id, + network, + }); + } + + async getWOUSDBalances(address: string) { + return this.appToolkit.helpers.tokenBalanceHelper.getTokenBalances({ + address, + appId: ORIGIN_DOLLAR_DEFINITION.id, + groupId: ORIGIN_DOLLAR_DEFINITION.groups.wousd.id, + network: Network.ETHEREUM_MAINNET, + }); + } + + async getBalances(address: string) { + return presentBalanceFetcherResponse([ + { + label: `Wrapped OUSD`, + assets: await this.getWOUSDBalances(address), + }, + { + label: 'OGV Stake', + assets: await this.getStakeBalances(address), + }, + { + label: 'Reward', + assets: await this.getClaimableBalances(address), + }, + ]); + } +} diff --git a/src/apps/origin-dollar/ethereum/origin-dollar.rewards.contract-position-fetcher.ts b/src/apps/origin-dollar/ethereum/origin-dollar.rewards.contract-position-fetcher.ts new file mode 100644 index 000000000..8920615d7 --- /dev/null +++ b/src/apps/origin-dollar/ethereum/origin-dollar.rewards.contract-position-fetcher.ts @@ -0,0 +1,54 @@ +import { Inject } from '@nestjs/common'; + +import { IAppToolkit, APP_TOOLKIT } from '~app-toolkit/app-toolkit.interface'; +import { Register } from '~app-toolkit/decorators'; +import { getImagesFromToken, getLabelFromToken } from '~app-toolkit/helpers/presentation/image.present'; +import { ContractType } from '~position/contract.interface'; +import { PositionFetcher } from '~position/position-fetcher.interface'; +import { ContractPosition } from '~position/position.interface'; +import { Network } from '~types/network.interface'; + +import { OriginDollarContractFactory } from '../contracts'; +import { ORIGIN_DOLLAR_DEFINITION } from '../origin-dollar.definition'; + +const appId = ORIGIN_DOLLAR_DEFINITION.id; +const groupId = ORIGIN_DOLLAR_DEFINITION.groups.rewards.id; +const network = Network.ETHEREUM_MAINNET; + +@Register.ContractPositionFetcher({ appId, groupId, network }) +export class EthereumOriginDollarRewardsContractPositionFetcher implements PositionFetcher { + constructor( + @Inject(APP_TOOLKIT) private readonly appToolkit: IAppToolkit, + @Inject(OriginDollarContractFactory) private readonly originDollarContractFactory: OriginDollarContractFactory, + ) {} + + async getPositions() { + const appTokens = await this.appToolkit.getAppTokenPositions({ + appId: 'origin-dollar', + groupIds: ['veogv'], + network, + }); + + const ogv = appTokens.find(v => v.address === '0x0c4576ca1c365868e162554af8e385dc3e7c66d9'); + + if (!ogv) { + return []; + } + + const position: ContractPosition = { + type: ContractType.POSITION, + appId, + groupId, + address: ogv.address, + network, + tokens: [...appTokens], + dataProps: {}, + displayProps: { + label: `${getLabelFromToken(ogv)} Staking Rewards`, + images: getImagesFromToken(ogv), + }, + }; + + return [position]; + } +} diff --git a/src/apps/origin-dollar/ethereum/origin-dollar.veogv.token-fetcher.ts b/src/apps/origin-dollar/ethereum/origin-dollar.veogv.token-fetcher.ts new file mode 100644 index 000000000..95ac44dd2 --- /dev/null +++ b/src/apps/origin-dollar/ethereum/origin-dollar.veogv.token-fetcher.ts @@ -0,0 +1,129 @@ +import { Inject } from '@nestjs/common'; +import { ethers } from 'ethers'; + +import { IAppToolkit, APP_TOOLKIT } from '~app-toolkit/app-toolkit.interface'; +import { Register } from '~app-toolkit/decorators'; +import { getLabelFromToken } from '~app-toolkit/helpers/presentation/image.present'; +import { ContractType } from '~position/contract.interface'; +import { PositionFetcher } from '~position/position-fetcher.interface'; +import { AppTokenPosition } from '~position/position.interface'; +import { Network } from '~types/network.interface'; + +import { OriginDollarContractFactory } from '../contracts'; +import { ORIGIN_DOLLAR_DEFINITION } from '../origin-dollar.definition'; + +const appId = ORIGIN_DOLLAR_DEFINITION.id; +const groupId = ORIGIN_DOLLAR_DEFINITION.groups.veogv.id; +const network = Network.ETHEREUM_MAINNET; + +export type VeOGVTokenDataProps = { + apy: number; + totalValueLocked: number; +}; +const oneEther = ethers.constants.WeiPerEther; +// Daily emissions in format: start_timestamp, end_timestamp, daily emissions +// Ref: https://github.com/OriginProtocol/ousd-governance/blob/955e2924f50b452d66a2506c00a293da4d8493d0/client/utils/apy.tsx#L6-L17 +const dailyEmissionsTable = [ + [0, 1660176000, 3333333], + [1660176000, 1665360000, 2666667], + [1665360000, 1675728000, 1866667], + [1675728000, 1696464000, 1120000], + [1696464000, 1727568000, 560000], + [1727568000, 1779408000, 224000], + [1779408000, 1862352000, 67200], +]; +const floatToBN = v => ethers.utils.parseUnits(v.toString(), 18); +const toBN = v => ethers.BigNumber.from(v); +const format = v => ethers.utils.formatUnits(v); +const stamp = () => Date.now() / 1000; + +/** + * Calculate the expectd maximum rewards APY for a stake + * + * Ref: https://github.com/OriginProtocol/ousd-governance/blob/955e2924f50b452d66a2506c00a293da4d8493d0/client/utils/apy.tsx#L27-L56 + * + * @param ogv {BigNumber} - The amount of OGV for the stake + * @param veogv {BigNumber} - The amount of veOGV expected to be given for the stake + * @param totalSupplyVeOGV {BigNumber} - The total supply of veOGV + * @return {number} A decimal representation of expected APY for a 4 year stake + */ +function getRewardsApy(ogv, veogv, totalSupplyVeOGV) { + const pctShare = veogv.mul(oneEther).div(totalSupplyVeOGV.add(veogv)); + const now = stamp(); + const dailyEmissionsRow = dailyEmissionsTable.find(([startTime, endTime]) => now > startTime && now < endTime); + const dailyEmissions = dailyEmissionsRow ? dailyEmissionsRow[2] : 0; + const dailyRewards = toBN(dailyEmissions).mul(pctShare); + const yearlyRewards = dailyRewards.mul(floatToBN(365.25)).div(oneEther); + const apr = yearlyRewards.mul(oneEther).div(ogv); + return parseFloat(format(apr)); +} + +@Register.TokenPositionFetcher({ appId, groupId, network }) +export class EthereumOriginDollarVeogvTokenFetcher implements PositionFetcher { + constructor( + @Inject(APP_TOOLKIT) private readonly appToolkit: IAppToolkit, + @Inject(OriginDollarContractFactory) private readonly originDollarContractFactory: OriginDollarContractFactory, + ) {} + + async getPositions() { + const baseTokens = await this.appToolkit.getBaseTokenPrices(network); + const multicall = this.appToolkit.getMulticall(network); + + const ogv = baseTokens.find(v => v.address === '0x9c354503c38481a7a7a51629142963f98ecc12d0'); + if (!ogv) return []; + + const contract = this.originDollarContractFactory.veogv({ + address: '0x0c4576ca1c365868e162554af8e385dc3e7c66d9', + network, + }); + + // Amount we'll use to calculate APY (1000 OGV) + const stakeAmount = ethers.BigNumber.from('1000000000000000000000'); + + // Get contract data + const [supplyRaw, [expectedVeOGV], ogvBalance] = await Promise.all([ + multicall.wrap(contract).totalSupply(), + // 1000e18 @ 4 year stake (1461 days) + multicall.wrap(contract).previewPoints(stakeAmount, ethers.BigNumber.from('126230400')), + multicall + .wrap(this.appToolkit.globalContracts.erc20({ network, address: ogv.address })) + .balanceOf(contract.address), + ]); + + // Calculate TVL in USD + const supply = parseFloat(format(supplyRaw)); + const totalValueLocked = parseFloat( + format(supplyRaw.mul(ethers.utils.parseUnits(ogv.price.toString(), 18)).div(oneEther)), + ); + const apy = getRewardsApy(stakeAmount, expectedVeOGV, supplyRaw); + + // Approximate value of position + const ratio = parseFloat(format(supplyRaw.mul(oneEther).div(ogvBalance))); + const price = ogv.price / ratio; + + const token: AppTokenPosition = { + type: ContractType.APP_TOKEN, + appId, + groupId, + address: contract.address, + network, + symbol: 'veOGV', + decimals: 18, + supply, + tokens: [ogv], + pricePerShare: [price], + price, + dataProps: { + apy, + totalValueLocked, + }, + displayProps: { + label: `Vote Escrowed ${getLabelFromToken(ogv)}`, + secondaryLabel: `Up to ${(apy * 100).toFixed(3)}% APY`, + images: ['https://governance.ousd.com/veogv.svg'], + }, + }; + + return [token]; + } +} diff --git a/src/apps/origin-dollar/ethereum/origin-dollar.wousd.token-fetcher.ts b/src/apps/origin-dollar/ethereum/origin-dollar.wousd.token-fetcher.ts new file mode 100644 index 000000000..3333ffc66 --- /dev/null +++ b/src/apps/origin-dollar/ethereum/origin-dollar.wousd.token-fetcher.ts @@ -0,0 +1,83 @@ +import { Inject } from '@nestjs/common'; +import { ethers } from 'ethers'; + +import { IAppToolkit, APP_TOOLKIT } from '~app-toolkit/app-toolkit.interface'; +import { Register } from '~app-toolkit/decorators'; +import { getLabelFromToken, getImagesFromToken } from '~app-toolkit/helpers/presentation/image.present'; +import { ContractType } from '~position/contract.interface'; +import { PositionFetcher } from '~position/position-fetcher.interface'; +import { AppTokenPosition } from '~position/position.interface'; +import { Network } from '~types/network.interface'; + +import { OriginDollarContractFactory } from '../contracts'; +import { ORIGIN_DOLLAR_DEFINITION } from '../origin-dollar.definition'; + +const appId = ORIGIN_DOLLAR_DEFINITION.id; +const groupId = ORIGIN_DOLLAR_DEFINITION.groups.wousd.id; +const network = Network.ETHEREUM_MAINNET; + +export type VeOGVTokenDataProps = { + totalValueLocked: number; +}; + +const oneEther = ethers.constants.WeiPerEther; +const format = v => ethers.utils.formatUnits(v); + +@Register.TokenPositionFetcher({ appId, groupId, network }) +export class EthereumOriginDollarWousdTokenFetcher implements PositionFetcher { + constructor( + @Inject(APP_TOOLKIT) private readonly appToolkit: IAppToolkit, + @Inject(OriginDollarContractFactory) private readonly originDollarContractFactory: OriginDollarContractFactory, + ) {} + + async getPositions() { + const baseTokens = await this.appToolkit.getBaseTokenPrices(network); + const multicall = this.appToolkit.getMulticall(network); + + const ousd = baseTokens.find(v => v.address === '0x2a8e1e676ec238d8a992307b495b45b3feaa5e86'); + if (!ousd) return []; + + const contract = this.originDollarContractFactory.wousd({ + address: '0xd2af830e8cbdfed6cc11bab697bb25496ed6fa62', + network, + }); + + // Get contract data + const [supplyRaw, ousdBalance] = await Promise.all([ + multicall.wrap(contract).totalSupply(), + multicall + .wrap(this.appToolkit.globalContracts.erc20({ network, address: ousd.address })) + .balanceOf(contract.address), + ]); + + const supply = parseFloat(format(supplyRaw)); + const totalValueLocked = parseFloat( + format(supplyRaw.mul(ethers.utils.parseUnits(ousd.price.toString(), 18)).div(oneEther)), + ); + const ratio = parseFloat(format(supplyRaw.mul(oneEther).div(ousdBalance))); + const price = ousd.price / ratio; + + const token: AppTokenPosition = { + type: ContractType.APP_TOKEN, + appId, + groupId, + address: contract.address, + network, + symbol: 'wOUSD', + decimals: 18, + supply, + tokens: [ousd], + pricePerShare: [price], + price, + dataProps: { + totalValueLocked, + }, + displayProps: { + label: `Wrapped ${getLabelFromToken(ousd)}`, + images: getImagesFromToken(ousd), + }, + }; + + return [token]; + } +} diff --git a/src/apps/origin-dollar/helpers/ogv-rewards.balance-helper.ts b/src/apps/origin-dollar/helpers/ogv-rewards.balance-helper.ts new file mode 100644 index 000000000..92a1b9fa5 --- /dev/null +++ b/src/apps/origin-dollar/helpers/ogv-rewards.balance-helper.ts @@ -0,0 +1,54 @@ +import { Inject, Injectable } from '@nestjs/common'; + +import { APP_TOOLKIT, IAppToolkit } from '~app-toolkit/app-toolkit.interface'; +import { drillBalance } from '~app-toolkit/helpers/balance/token-balance.helper'; +import { ContractPositionBalance } from '~position/position-balance.interface'; +import { Network } from '~types/network.interface'; + +import { OriginDollarContractFactory } from '../contracts'; + +type OGVRewardsParams = { + appId: string; + groupId: string; + network: Network; + address: string; +}; + +@Injectable() +export class OGVRewardsBalanceHelper { + constructor( + @Inject(APP_TOOLKIT) private readonly appToolkit: IAppToolkit, + @Inject(OriginDollarContractFactory) private readonly contractFactory: OriginDollarContractFactory, + ) {} + + async getClaimableBalances({ appId, network, address }: OGVRewardsParams) { + const multicall = this.appToolkit.getMulticall(network); + + // Retrieve reward position + const [contractPosition] = await this.appToolkit.getAppContractPositions({ + network, + appId, + groupIds: ['rewards'], + }); + + if (!contractPosition) { + return []; + } + + const veogv = await this.contractFactory.veogv({ + network, + address: contractPosition.address, + }); + + const balanceRaw = await multicall.wrap(veogv).previewRewards(address); + const tokenBalance = drillBalance(contractPosition.tokens[0], balanceRaw.toString()); + + const contractPositionBalance: ContractPositionBalance = { + ...contractPosition, + tokens: [tokenBalance], + balanceUSD: tokenBalance.balanceUSD, + }; + + return [contractPositionBalance]; + } +} diff --git a/src/apps/origin-dollar/index.ts b/src/apps/origin-dollar/index.ts new file mode 100644 index 000000000..f28aec482 --- /dev/null +++ b/src/apps/origin-dollar/index.ts @@ -0,0 +1,3 @@ +export { ORIGIN_DOLLAR_DEFINITION, OriginDollarAppDefinition } from './origin-dollar.definition'; +export { OriginDollarAppModule } from './origin-dollar.module'; +export { OriginDollarContractFactory } from './contracts'; diff --git a/src/apps/origin-dollar/origin-dollar.definition.ts b/src/apps/origin-dollar/origin-dollar.definition.ts new file mode 100644 index 000000000..24c08f669 --- /dev/null +++ b/src/apps/origin-dollar/origin-dollar.definition.ts @@ -0,0 +1,51 @@ +import { Register } from '~app-toolkit/decorators'; +import { appDefinition, AppDefinition } from '~app/app.definition'; +import { AppAction, AppTag, GroupType } from '~app/app.interface'; +import { Network } from '~types/network.interface'; + +export const ORIGIN_DOLLAR_DEFINITION = appDefinition({ + id: 'origin-dollar', + name: 'Origin Dollar', + description: 'Origin Dollar is the first stablecoin that earns yield while sitting in your wallet', + url: 'https://www.ousd.com/', + + groups: { + veogv: { + id: 'veogv', + type: GroupType.TOKEN, + label: 'veOGV', + }, + + rewards: { + id: 'rewards', + type: GroupType.POSITION, + label: 'OGV Rewards', + }, + + wousd: { + id: 'wousd', + type: GroupType.TOKEN, + label: 'wOUSD', + }, + }, + + tags: [AppTag.ELASTIC_FINANCE, AppTag.FARMING, AppTag.STABLECOIN, AppTag.STAKING, AppTag.YIELD_AGGREGATOR], + + keywords: [], + links: {}, + + supportedNetworks: { + [Network.ETHEREUM_MAINNET]: [AppAction.VIEW], + }, + + primaryColor: '#fff', +}); + +@Register.AppDefinition(ORIGIN_DOLLAR_DEFINITION.id) +export class OriginDollarAppDefinition extends AppDefinition { + constructor() { + super(ORIGIN_DOLLAR_DEFINITION); + } +} + +export default ORIGIN_DOLLAR_DEFINITION; diff --git a/src/apps/origin-dollar/origin-dollar.module.ts b/src/apps/origin-dollar/origin-dollar.module.ts new file mode 100644 index 000000000..677817c2f --- /dev/null +++ b/src/apps/origin-dollar/origin-dollar.module.ts @@ -0,0 +1,24 @@ +import { Register } from '~app-toolkit/decorators'; +import { AbstractApp } from '~app/app.dynamic-module'; + +import { OriginDollarContractFactory } from './contracts'; +import { EthereumOriginDollarBalanceFetcher } from './ethereum/origin-dollar.balance-fetcher'; +import { EthereumOriginDollarRewardsContractPositionFetcher } from './ethereum/origin-dollar.rewards.contract-position-fetcher'; +import { EthereumOriginDollarVeogvTokenFetcher } from './ethereum/origin-dollar.veogv.token-fetcher'; +import { EthereumOriginDollarWousdTokenFetcher } from './ethereum/origin-dollar.wousd.token-fetcher'; +import { OGVRewardsBalanceHelper } from './helpers/ogv-rewards.balance-helper'; +import { OriginDollarAppDefinition, ORIGIN_DOLLAR_DEFINITION } from './origin-dollar.definition'; + +@Register.AppModule({ + appId: ORIGIN_DOLLAR_DEFINITION.id, + providers: [ + EthereumOriginDollarBalanceFetcher, + EthereumOriginDollarRewardsContractPositionFetcher, + EthereumOriginDollarVeogvTokenFetcher, + EthereumOriginDollarWousdTokenFetcher, + OGVRewardsBalanceHelper, + OriginDollarAppDefinition, + OriginDollarContractFactory, + ], +}) +export class OriginDollarAppModule extends AbstractApp() {} From aff680a530d4df7648c77f1111fed9d3450fdcd1 Mon Sep 17 00:00:00 2001 From: Mike Shultz Date: Mon, 25 Jul 2022 11:05:14 -0600 Subject: [PATCH 2/4] fix(origin-dollar): fixes pricePerShare calculation and adds liquidity for veogv --- .../ethereum/origin-dollar.veogv.token-fetcher.ts | 10 ++++++---- .../ethereum/origin-dollar.wousd.token-fetcher.ts | 2 +- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/apps/origin-dollar/ethereum/origin-dollar.veogv.token-fetcher.ts b/src/apps/origin-dollar/ethereum/origin-dollar.veogv.token-fetcher.ts index 95ac44dd2..15eeaa723 100644 --- a/src/apps/origin-dollar/ethereum/origin-dollar.veogv.token-fetcher.ts +++ b/src/apps/origin-dollar/ethereum/origin-dollar.veogv.token-fetcher.ts @@ -3,6 +3,7 @@ import { ethers } from 'ethers'; import { IAppToolkit, APP_TOOLKIT } from '~app-toolkit/app-toolkit.interface'; import { Register } from '~app-toolkit/decorators'; +import { buildDollarDisplayItem } from '~app-toolkit/helpers/presentation/display-item.present'; import { getLabelFromToken } from '~app-toolkit/helpers/presentation/image.present'; import { ContractType } from '~position/contract.interface'; import { PositionFetcher } from '~position/position-fetcher.interface'; @@ -18,7 +19,7 @@ const network = Network.ETHEREUM_MAINNET; export type VeOGVTokenDataProps = { apy: number; - totalValueLocked: number; + liquidity: number; }; const oneEther = ethers.constants.WeiPerEther; // Daily emissions in format: start_timestamp, end_timestamp, daily emissions @@ -92,7 +93,7 @@ export class EthereumOriginDollarVeogvTokenFetcher implements PositionFetcher Date: Mon, 25 Jul 2022 11:12:29 -0600 Subject: [PATCH 3/4] fix(origin-dollar): use veogv logo in assets rather than public URL --- ...0c4576ca1c365868e162554af8e385dc3e7c66d9.png | Bin 0 -> 63544 bytes .../origin-dollar.veogv.token-fetcher.ts | 4 ++-- 2 files changed, 2 insertions(+), 2 deletions(-) create mode 100644 src/apps/origin-dollar/assets/0x0c4576ca1c365868e162554af8e385dc3e7c66d9.png diff --git a/src/apps/origin-dollar/assets/0x0c4576ca1c365868e162554af8e385dc3e7c66d9.png b/src/apps/origin-dollar/assets/0x0c4576ca1c365868e162554af8e385dc3e7c66d9.png new file mode 100644 index 0000000000000000000000000000000000000000..1b4e9f82556745ee56721048cb7a937aed3b3f29 GIT binary patch literal 63544 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 literal 0 HcmV?d00001 diff --git a/src/apps/origin-dollar/ethereum/origin-dollar.veogv.token-fetcher.ts b/src/apps/origin-dollar/ethereum/origin-dollar.veogv.token-fetcher.ts index 15eeaa723..a3fad035f 100644 --- a/src/apps/origin-dollar/ethereum/origin-dollar.veogv.token-fetcher.ts +++ b/src/apps/origin-dollar/ethereum/origin-dollar.veogv.token-fetcher.ts @@ -4,7 +4,7 @@ import { ethers } from 'ethers'; import { IAppToolkit, APP_TOOLKIT } from '~app-toolkit/app-toolkit.interface'; import { Register } from '~app-toolkit/decorators'; import { buildDollarDisplayItem } from '~app-toolkit/helpers/presentation/display-item.present'; -import { getLabelFromToken } from '~app-toolkit/helpers/presentation/image.present'; +import { getAppAssetImage, getLabelFromToken } from '~app-toolkit/helpers/presentation/image.present'; import { ContractType } from '~position/contract.interface'; import { PositionFetcher } from '~position/position-fetcher.interface'; import { AppTokenPosition } from '~position/position.interface'; @@ -121,7 +121,7 @@ export class EthereumOriginDollarVeogvTokenFetcher implements PositionFetcher Date: Mon, 25 Jul 2022 11:17:36 -0600 Subject: [PATCH 4/4] fix(origin-dollar): user moment.js to derive durations instead of hardcoding seconds --- .../ethereum/origin-dollar.veogv.token-fetcher.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/apps/origin-dollar/ethereum/origin-dollar.veogv.token-fetcher.ts b/src/apps/origin-dollar/ethereum/origin-dollar.veogv.token-fetcher.ts index a3fad035f..99a701dc4 100644 --- a/src/apps/origin-dollar/ethereum/origin-dollar.veogv.token-fetcher.ts +++ b/src/apps/origin-dollar/ethereum/origin-dollar.veogv.token-fetcher.ts @@ -1,4 +1,5 @@ import { Inject } from '@nestjs/common'; +import moment from 'moment'; import { ethers } from 'ethers'; import { IAppToolkit, APP_TOOLKIT } from '~app-toolkit/app-toolkit.interface'; @@ -80,12 +81,13 @@ export class EthereumOriginDollarVeogvTokenFetcher implements PositionFetcher