Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

- [\#589](https://github.com/cosmos/evm/pull/589) Remove parallelization blockers via migration from transient to object store, refactoring of gas, indexing, and bloom utilities.
- [\#768](https://github.com/cosmos/evm/pull/768) Added ICS-02 Client Router precompile
- [\#804](https://github.com/cosmos/evm/pull/804) Bank precompile redesign.

### BUG FIXES

Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ test-unit-cover: run-tests
@echo "🔀 Merging evmd coverage into root coverage..."
@tail -n +2 evmd/coverage_evmd.txt >> coverage.txt && rm evmd/coverage_evmd.txt
@echo "🧹 Filtering ignored files from coverage.txt..."
@grep -v -E '/cmd/|/client/|/proto/|/testutil/|/mocks/|/test_.*\.go:|\.pb\.go:|\.pb\.gw\.go:|/x/[^/]+/module\.go:|/scripts/|/ibc/testing/|/version/|\.md:|\.pulsar\.go:' coverage.txt > tmp_coverage.txt && mv tmp_coverage.txt coverage.txt
@grep -v -E '/cmd/|/client/|/proto/|/testutil/|/mocks/|/test_.*\.go:|\.pb\.go:|\.pb\.gw\.go:|\.abi\.go:|/x/[^/]+/module\.go:|/scripts/|/ibc/testing/|/version/|\.md:|\.pulsar\.go:' coverage.txt > tmp_coverage.txt && mv tmp_coverage.txt coverage.txt

test: test-unit

Expand Down
1 change: 1 addition & 0 deletions evmd/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -462,6 +462,7 @@ func NewExampleApp(
*app.StakingKeeper,
app.DistrKeeper,
app.PreciseBankKeeper,
app.BankKeeper,
&app.Erc20Keeper,
&app.TransferKeeper,
app.IBCKeeper.ChannelKeeper,
Expand Down
3 changes: 2 additions & 1 deletion evmd/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ require (
github.com/cosmos/evm v0.2.0
github.com/cosmos/gogoproto v1.7.2
github.com/cosmos/ibc-go/v10 v10.0.0-beta.0.0.20251027215440-22f0033d0aee
github.com/ethereum/go-ethereum v1.16.5
github.com/ethereum/go-ethereum v1.16.7
github.com/onsi/ginkgo/v2 v2.23.4
github.com/onsi/gomega v1.38.0
github.com/spf13/cast v1.10.0
Expand Down Expand Up @@ -242,6 +242,7 @@ require (
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
github.com/tyler-smith/go-bip39 v1.1.0 // indirect
github.com/ulikunitz/xz v0.5.15 // indirect
github.com/yihuang/go-abi v0.1.1 // indirect
github.com/yusufpapurcu/wmi v1.2.4 // indirect
github.com/zeebo/errs v1.4.0 // indirect
github.com/zondax/golem v0.27.0 // indirect
Expand Down
4 changes: 4 additions & 0 deletions evmd/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -972,6 +972,8 @@ github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70
github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc=
github.com/tendermint/go-amino v0.16.0 h1:GyhmgQKvqF82e2oZeuMSp9JTN0N09emoSZlb2lyGa2E=
github.com/tendermint/go-amino v0.16.0/go.mod h1:TQU0M1i/ImAo+tYpZi73AU3V/dKeCoMC9Sphe2ZwGME=
github.com/test-go/testify v1.1.4 h1:Tf9lntrKUMHiXQ07qBScBTSA0dhYQlu83hswqelv1iE=
github.com/test-go/testify v1.1.4/go.mod h1:rH7cfJo/47vWGdi4GPj16x3/t1xGOj2YxzmNQzk2ghU=
github.com/tidwall/gjson v1.14.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY=
github.com/tidwall/gjson v1.18.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
Expand Down Expand Up @@ -1002,6 +1004,8 @@ github.com/urfave/cli/v2 v2.27.5/go.mod h1:3Sevf16NykTbInEnD0yKkjDAeZDS0A6bzhBH5
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 h1:gEOO8jv9F4OT7lGCjxCBTO/36wtF6j2nSip77qHd4x4=
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1/go.mod h1:Ohn+xnUBiLI6FVj/9LpzZWtj1/D6lUovWYBkxHVV3aM=
github.com/yihuang/go-abi v0.1.1 h1:5MHV/wOz0wywsb9IhaZmHLhBNAF5EzSXisPyv3gN5Rs=
github.com/yihuang/go-abi v0.1.1/go.mod h1:btymTlqoiLCR8Gj5bppalyNPSzQYUfK6YROYsihjGS4=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
Expand Down
4 changes: 3 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ require (
github.com/cosmos/ledger-cosmos-go v0.16.0
github.com/creachadair/tomledit v0.0.28
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc
github.com/ethereum/go-ethereum v1.16.5
github.com/ethereum/go-ethereum v1.16.7
github.com/gogo/protobuf v1.3.2
github.com/golang/protobuf v1.5.4
github.com/gorilla/mux v1.8.1
Expand All @@ -46,6 +46,7 @@ require (
github.com/tidwall/gjson v1.18.0
github.com/tidwall/sjson v1.2.5
github.com/tyler-smith/go-bip39 v1.1.0
github.com/yihuang/go-abi v0.1.1
github.com/zondax/hid v0.9.2
go.uber.org/mock v0.6.0
golang.org/x/crypto v0.45.0
Expand Down Expand Up @@ -266,6 +267,7 @@ require (
go.yaml.in/yaml/v3 v3.0.4 // indirect
golang.org/x/arch v0.21.0 // indirect
golang.org/x/exp v0.0.0-20250506013437-ce4c2cf36ca6 // indirect
golang.org/x/mod v0.29.0 // indirect
golang.org/x/oauth2 v0.31.0 // indirect
golang.org/x/sys v0.38.0 // indirect
golang.org/x/term v0.37.0 // indirect
Expand Down
6 changes: 6 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -952,6 +952,8 @@ github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70
github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc=
github.com/tendermint/go-amino v0.16.0 h1:GyhmgQKvqF82e2oZeuMSp9JTN0N09emoSZlb2lyGa2E=
github.com/tendermint/go-amino v0.16.0/go.mod h1:TQU0M1i/ImAo+tYpZi73AU3V/dKeCoMC9Sphe2ZwGME=
github.com/test-go/testify v1.1.4 h1:Tf9lntrKUMHiXQ07qBScBTSA0dhYQlu83hswqelv1iE=
github.com/test-go/testify v1.1.4/go.mod h1:rH7cfJo/47vWGdi4GPj16x3/t1xGOj2YxzmNQzk2ghU=
github.com/tidwall/gjson v1.14.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY=
github.com/tidwall/gjson v1.18.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
Expand Down Expand Up @@ -982,6 +984,8 @@ github.com/urfave/cli/v2 v2.27.5/go.mod h1:3Sevf16NykTbInEnD0yKkjDAeZDS0A6bzhBH5
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 h1:gEOO8jv9F4OT7lGCjxCBTO/36wtF6j2nSip77qHd4x4=
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1/go.mod h1:Ohn+xnUBiLI6FVj/9LpzZWtj1/D6lUovWYBkxHVV3aM=
github.com/yihuang/go-abi v0.1.1 h1:5MHV/wOz0wywsb9IhaZmHLhBNAF5EzSXisPyv3gN5Rs=
github.com/yihuang/go-abi v0.1.1/go.mod h1:btymTlqoiLCR8Gj5bppalyNPSzQYUfK6YROYsihjGS4=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
Expand Down Expand Up @@ -1089,6 +1093,8 @@ golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.29.0 h1:HV8lRxZC4l2cr3Zq1LvtOsi/ThTgWnUk/y64QSs8GwA=
golang.org/x/mod v0.29.0/go.mod h1:NyhrlYXJ2H4eJiRy/WDBO6HMqZQ6q9nk4JzS3NuCK+w=
golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
Expand Down
1 change: 1 addition & 0 deletions precompiles/bank/ERC20.bin
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
60a0604052346102315761107d8038038061001981610235565b9283398101906040818303126102315780516001600160401b0381116102315781019082601f830112156102315781516001600160401b03811161021d5761006a601f8201601f1916602001610235565b9381855260208285010111610231576020815f92828096018388015e8501015201516001600160a01b03811681036102315781516001600160401b03811161021d575f54600181811c91168015610213575b60208210146101ff57601f811161019d575b50602092601f821160011461013e57928192935f92610133575b50508160011b915f199060031b1c1916175f555b608052604051610e22908161025b823960805181818161030a015281816103c10152818161048e0152818161057f0152610c660152f35b015190505f806100e8565b601f198216935f8052805f20915f5b868110610185575083600195961061016d575b505050811b015f556100fc565b01515f1960f88460031b161c191690555f8080610160565b9192602060018192868501518155019401920161014d565b5f80527f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563601f830160051c810191602084106101f5575b601f0160051c01905b8181106101ea57506100ce565b5f81556001016101dd565b90915081906101d4565b634e487b7160e01b5f52602260045260245ffd5b90607f16906100bc565b634e487b7160e01b5f52604160045260245ffd5b5f80fd5b6040519190601f01601f191682016001600160401b0381118382101761021d5760405256fe6080806040526004361015610012575f80fd5b5f3560e01c90816306fdde03146108a557508063095ea7b3146107f857806318160ddd1461078d57806323b872dd146105f9578063313ce567146104fb57806370a08231146103e557806376cdb03b1461037757806395d89b4114610287578063a9059cbb14610238578063c370b042146101255763dd62ed3e14610095575f80fd5b346101215760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610121576100cc610954565b73ffffffffffffffffffffffffffffffffffffffff6100e9610977565b91165f52600160205273ffffffffffffffffffffffffffffffffffffffff60405f2091165f52602052602060405f2054604051908152f35b5f80fd5b34610121575f7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610121576040515f5f546101628161099a565b80845290600181169081156101f6575060011461019a575b6101968361018a818503826109eb565b6040519182918261090c565b0390f35b5f8080527f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563939250905b8082106101dc5750909150810160200161018a61017a565b9192600181602092548385880101520191019092916101c4565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660208086019190915291151560051b8401909101915061018a905061017a565b346101215760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101215761027c610272610954565b6024359033610ba5565b602060405160018152f35b34610121575f7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610121576040517f41bb0559000000000000000000000000000000000000000000000000000000008152602060048201525f81806102f160248201610aea565b038173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000165afa801561036c57610196915f9161034a575b506040519182918261090c565b61036691503d805f833e61035e81836109eb565b810190610a59565b8261033d565b6040513d5f823e3d90fd5b34610121575f7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261012157602060405173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b346101215760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101215761041c610954565b73ffffffffffffffffffffffffffffffffffffffff604051917fb9b092c8000000000000000000000000000000000000000000000000000000008352166004820152604060248201526020818061047560448201610aea565b038173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000165afa801561036c575f906104c8575b602090604051908152f35b506020813d6020116104f3575b816104e2602093836109eb565b8101031261012157602090516104bd565b3d91506104d5565b34610121575f7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610121576040517f3b2b3204000000000000000000000000000000000000000000000000000000008152602060048201526020818061056660248201610aea565b038173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000165afa801561036c575f906105bc575b60209060ff60405191168152f35b506020813d6020116105f1575b816105d6602093836109eb565b81010312610121575160ff81168103610121576020906105ae565b3d91506105c9565b346101215760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261012157610630610954565b610638610977565b6044359073ffffffffffffffffffffffffffffffffffffffff831692835f52600160205260405f2073ffffffffffffffffffffffffffffffffffffffff33165f5260205260405f20547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81106106b4575b5061027c9350610ba5565b83811061075957841561072d5733156107015761027c945f52600160205260405f2073ffffffffffffffffffffffffffffffffffffffff33165f526020528360405f2091039055846106a9565b7f94280d62000000000000000000000000000000000000000000000000000000005f525f60045260245ffd5b7fe602df05000000000000000000000000000000000000000000000000000000005f525f60045260245ffd5b83907ffb8f41b2000000000000000000000000000000000000000000000000000000005f523360045260245260445260645ffd5b34610121575f7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610121576040517fc415db13000000000000000000000000000000000000000000000000000000008152602060048201526020818061047560248201610aea565b346101215760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101215761082f610954565b60243590331561072d5773ffffffffffffffffffffffffffffffffffffffff1690811561070157335f52600160205260405f20825f526020528060405f20556040519081527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560203392a3602060405160018152f35b34610121575f7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610121577f5b43bc99000000000000000000000000000000000000000000000000000000008152602060048201525f81806102f160248201610aea565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f602060409481855280519182918282880152018686015e5f8582860101520116010190565b6004359073ffffffffffffffffffffffffffffffffffffffff8216820361012157565b6024359073ffffffffffffffffffffffffffffffffffffffff8216820361012157565b90600182811c921680156109e1575b60208310146109b457565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b91607f16916109a9565b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff821117610a2c57604052565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b6020818303126101215780519067ffffffffffffffff8211610121570181601f820112156101215780519067ffffffffffffffff8211610a2c5760405192610ac960207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f86011601856109eb565b8284526020838301011161012157815f9260208093018386015e8301015290565b905f915f5490610af98261099a565b8082529160018116908115610b6b5750600114610b14575050565b5f8080529293509091907f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5635b838310610b51575060209250010190565b600181602092949394548385870101520191019190610b40565b60209495507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0091509291921683830152151560051b010190565b73ffffffffffffffffffffffffffffffffffffffff16908115610dc05773ffffffffffffffffffffffffffffffffffffffff16918215610d94576040517f1af716ba000000000000000000000000000000000000000000000000000000008152826004820152836024820152816044820152608060648201525f815f54610c2b8161099a565b908160848401526001811690815f14610d545750600114610cfc575b508060209203815f73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000165af1801561036c57610cc1575b5060207fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91604051908152a3565b6020813d602011610cf4575b81610cda602093836109eb565b810103126101215751801515810361012157506020610c93565b3d9150610ccd565b5f8080529192507f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5635b818310610d3a575050810160a4019080610c47565b805483860160a40152849350602090920191600101610d25565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660a48085019190915291151560051b83019091019250819050610c47565b7fec442f05000000000000000000000000000000000000000000000000000000005f525f60045260245ffd5b7f96c6fd1e000000000000000000000000000000000000000000000000000000005f525f60045260245ffdfea26469706673582212209877ef265ed97e48971f94b7bbf60b6475123ef4a1b88d7af8ae4a8f4526564f64736f6c634300081e0033
114 changes: 114 additions & 0 deletions precompiles/bank/ERC20.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

interface IBankPrecompile {
// queries
function name(string memory denom) external view returns (string memory);
function symbol(string memory denom) external view returns (string memory);
function decimals(string memory denom) external view returns (uint8);
function totalSupply(string memory denom) external view returns (uint256);
function balanceOf(address account, string memory denom) external view returns (uint256);

function transferFrom(address from, address to, uint256 value, string memory denom) external returns (bool);
}

contract ERC20 {
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);

error ERC20InvalidSender(address sender);
error ERC20InvalidReceiver(address receiver);
error ERC20InsufficientAllowance(address spender, uint256 allowance, uint256 needed);
error ERC20InvalidApprover(address approver);
error ERC20InvalidSpender(address spender);


string public denom;
mapping(address account => mapping(address spender => uint256)) public allowance;

IBankPrecompile public immutable bank;

constructor(string memory denom_, IBankPrecompile bank_) {
denom = denom_;
bank = bank_;
}

function name() public view returns (string memory) {
return bank.name(denom);
}

function symbol() public view returns (string memory) {
return bank.symbol(denom);
}

function decimals() public view returns (uint8) {
return bank.decimals(denom);
}

function totalSupply() public view returns (uint256) {
return bank.totalSupply(denom);
}

function balanceOf(address account) public view returns (uint256) {
return bank.balanceOf(account, denom);
}

function transfer(address to, uint256 value) public returns (bool) {
_transfer(msg.sender, to, value);
return true;
}

function approve(address spender, uint256 value) public returns (bool) {
_approve(msg.sender, spender, value);
return true;
}

function transferFrom(address from, address to, uint256 value) public returns (bool) {
address spender = msg.sender;
_spendAllowance(from, spender, value);
_transfer(from, to, value);
return true;
}

function _transfer(address from, address to, uint256 value) internal {
if (from == address(0)) {
revert ERC20InvalidSender(address(0));
}
if (to == address(0)) {
revert ERC20InvalidReceiver(address(0));
}

bank.transferFrom(from, to, value, denom);
emit Transfer(from, to, value);
}

function _approve(address owner, address spender, uint256 value) internal {
_approve(owner, spender, value, true);
}

function _approve(address owner, address spender, uint256 value, bool emitEvent) internal virtual {
if (owner == address(0)) {
revert ERC20InvalidApprover(address(0));
}
if (spender == address(0)) {
revert ERC20InvalidSpender(address(0));
}
allowance[owner][spender] = value;
if (emitEvent) {
emit Approval(owner, spender, value);
}
}

function _spendAllowance(address owner, address spender, uint256 value) internal virtual {
uint256 currentAllowance = allowance[owner][spender];
if (currentAllowance < type(uint256).max) {
if (currentAllowance < value) {
revert ERC20InsufficientAllowance(spender, currentAllowance, value);
}
unchecked {
_approve(owner, spender, currentAllowance - value, false);
}
}
}
}
Loading
Loading