├── .gitignore ├── LICENSE ├── README.md ├── examples ├── no-loss-lottery │ ├── README.md │ └── contracts │ │ └── NoLossLottery.sol ├── simple-ibc-transfer │ ├── README.md │ └── contracts │ │ └── ICS20Test.sol ├── simple-staker │ ├── README.md │ └── contracts │ │ └── SimpleStaker.sol └── staking-manager │ ├── README.md │ └── contracts │ └── StakingManager.sol ├── outposts ├── osmosis │ ├── README.md │ └── XCSOutpost.sol └── stride │ ├── LiquidStakeOutpost.sol │ └── README.md └── precompiles ├── abi ├── authorization.json ├── bech32.json ├── distribution.json ├── ics20.json ├── staking.json └── vesting.json ├── common ├── Authorization.sol ├── IICS20Authorization.sol └── Types.sol ├── stateful ├── Distribution.sol ├── ICS20.sol ├── Staking.sol └── Vesting.sol └── stateless └── Bech32.sol /.gitignore: -------------------------------------------------------------------------------- 1 | .idea -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU LESSER GENERAL PUBLIC LICENSE 2 | Version 3, 29 June 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | This version of the GNU Lesser General Public License incorporates 9 | the terms and conditions of version 3 of the GNU General Public 10 | License, supplemented by the additional permissions listed below. 11 | 12 | 0. Additional Definitions. 13 | 14 | As used herein, "this License" refers to version 3 of the GNU Lesser 15 | General Public License, and the "GNU GPL" refers to version 3 of the GNU 16 | General Public License. 17 | 18 | "The Library" refers to a covered work governed by this License, 19 | other than an Application or a Combined Work as defined below. 20 | 21 | An "Application" is any work that makes use of an interface provided 22 | by the Library, but which is not otherwise based on the Library. 23 | Defining a subclass of a class defined by the Library is deemed a mode 24 | of using an interface provided by the Library. 25 | 26 | A "Combined Work" is a work produced by combining or linking an 27 | Application with the Library. The particular version of the Library 28 | with which the Combined Work was made is also called the "Linked 29 | Version". 30 | 31 | The "Minimal Corresponding Source" for a Combined Work means the 32 | Corresponding Source for the Combined Work, excluding any source code 33 | for portions of the Combined Work that, considered in isolation, are 34 | based on the Application, and not on the Linked Version. 35 | 36 | The "Corresponding Application Code" for a Combined Work means the 37 | object code and/or source code for the Application, including any data 38 | and utility programs needed for reproducing the Combined Work from the 39 | Application, but excluding the System Libraries of the Combined Work. 40 | 41 | 1. Exception to Section 3 of the GNU GPL. 42 | 43 | You may convey a covered work under sections 3 and 4 of this License 44 | without being bound by section 3 of the GNU GPL. 45 | 46 | 2. Conveying Modified Versions. 47 | 48 | If you modify a copy of the Library, and, in your modifications, a 49 | facility refers to a function or data to be supplied by an Application 50 | that uses the facility (other than as an argument passed when the 51 | facility is invoked), then you may convey a copy of the modified 52 | version: 53 | 54 | a) under this License, provided that you make a good faith effort to 55 | ensure that, in the event an Application does not supply the 56 | function or data, the facility still operates, and performs 57 | whatever part of its purpose remains meaningful, or 58 | 59 | b) under the GNU GPL, with none of the additional permissions of 60 | this License applicable to that copy. 61 | 62 | 3. Object Code Incorporating Material from Library Header Files. 63 | 64 | The object code form of an Application may incorporate material from 65 | a header file that is part of the Library. You may convey such object 66 | code under terms of your choice, provided that, if the incorporated 67 | material is not limited to numerical parameters, data structure 68 | layouts and accessors, or small macros, inline functions and templates 69 | (ten or fewer lines in length), you do both of the following: 70 | 71 | a) Give prominent notice with each copy of the object code that the 72 | Library is used in it and that the Library and its use are 73 | covered by this License. 74 | 75 | b) Accompany the object code with a copy of the GNU GPL and this license 76 | document. 77 | 78 | 4. Combined Works. 79 | 80 | You may convey a Combined Work under terms of your choice that, 81 | taken together, effectively do not restrict modification of the 82 | portions of the Library contained in the Combined Work and reverse 83 | engineering for debugging such modifications, if you also do each of 84 | the following: 85 | 86 | a) Give prominent notice with each copy of the Combined Work that 87 | the Library is used in it and that the Library and its use are 88 | covered by this License. 89 | 90 | b) Accompany the Combined Work with a copy of the GNU GPL and this license 91 | document. 92 | 93 | c) For a Combined Work that displays copyright notices during 94 | execution, include the copyright notice for the Library among 95 | these notices, as well as a reference directing the user to the 96 | copies of the GNU GPL and this license document. 97 | 98 | d) Do one of the following: 99 | 100 | 0) Convey the Minimal Corresponding Source under the terms of this 101 | License, and the Corresponding Application Code in a form 102 | suitable for, and under terms that permit, the user to 103 | recombine or relink the Application with a modified version of 104 | the Linked Version to produce a modified Combined Work, in the 105 | manner specified by section 6 of the GNU GPL for conveying 106 | Corresponding Source. 107 | 108 | 1) Use a suitable shared library mechanism for linking with the 109 | Library. A suitable mechanism is one that (a) uses at run time 110 | a copy of the Library already present on the user's computer 111 | system, and (b) will operate properly with a modified version 112 | of the Library that is interface-compatible with the Linked 113 | Version. 114 | 115 | e) Provide Installation Information, but only if you would otherwise 116 | be required to provide such information under section 6 of the 117 | GNU GPL, and only to the extent that such information is 118 | necessary to install and execute a modified version of the 119 | Combined Work produced by recombining or relinking the 120 | Application with a modified version of the Linked Version. (If 121 | you use option 4d0, the Installation Information must accompany 122 | the Minimal Corresponding Source and Corresponding Application 123 | Code. If you use option 4d1, you must provide the Installation 124 | Information in the manner specified by section 6 of the GNU GPL 125 | for conveying Corresponding Source.) 126 | 127 | 5. Combined Libraries. 128 | 129 | You may place library facilities that are a work based on the 130 | Library side by side in a single library together with other library 131 | facilities that are not Applications and are not covered by this 132 | License, and convey such a combined library under terms of your 133 | choice, if you do both of the following: 134 | 135 | a) Accompany the combined library with a copy of the same work based 136 | on the Library, uncombined with any other library facilities, 137 | conveyed under the terms of this License. 138 | 139 | b) Give prominent notice with the combined library that part of it 140 | is a work based on the Library, and explaining where to find the 141 | accompanying uncombined form of the same work. 142 | 143 | 6. Revised Versions of the GNU Lesser General Public License. 144 | 145 | The Free Software Foundation may publish revised and/or new versions 146 | of the GNU Lesser General Public License from time to time. Such new 147 | versions will be similar in spirit to the present version, but may 148 | differ in detail to address new problems or concerns. 149 | 150 | Each version is given a distinguishing version number. If the 151 | Library as you received it specifies that a certain numbered version 152 | of the GNU Lesser General Public License "or any later version" 153 | applies to it, you have the option of following the terms and 154 | conditions either of that published version or of any later version 155 | published by the Free Software Foundation. If the Library as you 156 | received it does not specify a version number of the GNU Lesser 157 | General Public License, you may choose any version of the GNU Lesser 158 | General Public License ever published by the Free Software Foundation. 159 | 160 | If the Library as you received it specifies that a proxy can decide 161 | whether future versions of the GNU Lesser General Public License shall 162 | apply, that proxy's public statement of acceptance of any version is 163 | permanent authorization for you to choose that version for the 164 | Library. 165 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # EVM Extensions 2 | 3 | *🚧 NOTE: This project is still a work in progress 🚧* 4 | 5 | This repository contains all currently supported EVM Extensions 6 | (stateful precompiled contracts) for the [Evmos](https://evmos.org/) blockchain 7 | as well as a set of example contracts that can be used to test the capabilities of EVM Extensions. 8 | This repository is **WIP** and will be updated regularly 9 | as new contracts are added and new use cases are explored. 10 | 11 | ## What are EVM Extensions? 12 | 13 | Evmos’ unique implementation of stateful precompiles are called EVM Extensions. 14 | For the first time, this will allow not only blockchains 15 | but also individual applications to leverage and customize 16 | the functionality of IBC and other Cosmos SDK modules. 17 | Thus, these extensions push the EVM’s capabilities 18 | past its original specification without breaking equivalence with Ethereum’s execution layer. 19 | With the use of EVM Extensions, developers will be able to create their own business logic 20 | for connecting with other smart contracts and app chains in the Cosmos ecosystem. 21 | Applications will be freed from the confines of a single blockchain 22 | and able to make smart contract calls to IBC modules to communicate with other chains, 23 | send and receive assets between chains trustlessly, stake EVMOS tokens, 24 | and even manage accounts on other blockchains to access any functionality built elsewhere. 25 | 26 | ## Using this repository 27 | 28 | ### Prerequisites 29 | 30 | - Familiarity with Solidity interfaces - [Interfaces by example](https://solidity-by-example.org/interface/) 31 | - Familiarity with Cosmos SDK modules - `x/staking` `x/distribution`, `ics20`, and `x/authz`. 32 | - Familiarity with token approval mechanism similar to how `ERC20` tokens are approved for transfer. 33 | 34 | ### Structure 35 | 36 | - `examples/` contracts that utilize precompiled contracts to interact with the Cosmos SDK. 37 | - `outposts/` contracts that utilize the IBC extensions to interact with functionality on other chains like liquid staking on Stride and swapping on Omosis. 38 | - `precompiles/` contains Solidity interfaces for all currently supported precompiled contracts. 39 | - `abi/` contains the generated ABI for each precompile 40 | - `stateful/` - contains the Solidity interfaces for all stateful precompiles (ones that change state on the blockchain) 41 | - `stateless/` - contains the Solidity interfaces for all stateless precompiles (ones that do not change state on the blockchain) 42 | - `common/` - contains the Solidity interfaces for all common types used by precompiles 43 | 44 | -------------------------------------------------------------------------------- /examples/no-loss-lottery/README.md: -------------------------------------------------------------------------------- 1 | # No Loss Lottery 2 | 3 | This is an example of how to create a smart contract for a no-loss-lottery that utilizes 4 | the `Staking` and `Distribution` precompiled contracts - [NoLossLottery](./contracts/NoLossLottery.sol) 5 | 6 | A no-loss-lottery is a lottery where users deposit funds into a pool and delegate them to a validator. Once a day 7 | when the staking rewards are distributed, a random winner is picked from the pool of users based on their 8 | deposit amount (the higher deposit the better odds of winning the pool). The winner receives the total pot of rewards 9 | for that day. The users that did not win the lottery can withdraw their funds at any time without losing any 10 | of their initial deposit. 11 | 12 | The contract showcases how you can use the contract itself as a manager of funds to ensure 13 | that users cannot undelegate their funds at any time skewing the lottery results. 14 | 15 | **THIS IS NOT A COPY / PASTE CONTRACT** as it has certain limitations and is generally not production ready. 16 | 17 | ## Implementation 18 | 19 | ### Deposits 20 | 21 | The contract uses its own balance as a pool of funds that users can deposit into. The contract 22 | then uses the `Staking` precompile to delegate the funds to a validator. This ensures that the funds 23 | are locked and cannot be undelegated from outside the contract. The contract keeps track of which user 24 | delegated how much. 25 | 26 | ### Enter Lottery 27 | 28 | The contract allows users to enter the lottery by using the funds they have deposited into the contract 29 | to delegate to a validator. 30 | 31 | ### Draw Lottery 32 | 33 | The contract uses the `Distribution` precompile to calculate the rewards of the total pool of funds. Each user 34 | is assigned a number of tickets based on the amount of tokens they have delegated. Users are shuffled before each draw 35 | and the winner is selected based on the number of tickets they have and a random number. 36 | 37 | ### Withdraw Winnings 38 | 39 | The contract keeps track of which user won each round and allows them to withdraw the winnings in a separate 40 | transaction called `withdrawWinnings`. 41 | 42 | ### Exit Lottery 43 | 44 | The contract allows users to exit the lottery by undelegating their funds from the validator. **NOTE** only 45 | the total amount delegated can be undelegated for simplicity. Once the 14 day unbonding period is over the 46 | funds return to the contract and users can withdraw their funds using the `withdraw` function. 47 | 48 | ## Limitations 49 | 50 | ### No SafeMath 51 | 52 | The contract does not use OpenZeppelin's `SafeMath` library. This is fine for a showcase but be aware when deploying 53 | to testnet or mainnet you would need to use `SafeMath` to prevent overflows. 54 | 55 | ### No Oracle randomness 56 | 57 | The contract does not use an oracle for its random number generator or `shuffleParticipants` function. 58 | This is fine for a showcase but be aware when deploying to testnet or mainnet you would need a verifiable 59 | source of randomness. 60 | 61 | ### No Owner for the Contract 62 | 63 | The contract does not implement OpenZeppelin's `Ownable` contract. This can cause issues as anybody can 64 | execute the `pickWinner` function. Ideally some functions should be restricted to the owner of the contract 65 | like the `pickWinner` function which should be triggered off-chain a couple of seconds after the 66 | delegation rewards have been distributed 67 | 68 | ### No Multiple Validators 69 | 70 | The contract does not handle users delegating to multiple validators. This is for simplicity’s sake as this would require 71 | keeping track of which users have delegated to which validators and would require a more complex implementation. 72 | 73 | ### No Partial Exit Lottery 74 | 75 | The contract does not allow multiple undelegations with smaller amounts from the validator. 76 | This is for simplicity’s sake as this would require keeping track of which users have undelegated how much 77 | and would require a more complex implementation. 78 | -------------------------------------------------------------------------------- /examples/no-loss-lottery/contracts/NoLossLottery.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: LGPL-v3 2 | pragma solidity >=0.8.18; 3 | 4 | import "../../../precompiles/stateful/Staking.sol"; 5 | import "../../../precompiles/stateful/Distribution.sol"; 6 | 7 | contract NoLossLottery { 8 | 9 | /// @dev A struct that keeps track of the winners for each round. 10 | struct Winner { 11 | uint16 round; 12 | uint256 winningNumber; 13 | address winnerAddress; 14 | uint256 winingAmount; 15 | uint256 timestamp; 16 | } 17 | 18 | /// @dev A struct that keeps track of the unbonding delegations. 19 | struct UnbondingRequest { 20 | int64 completionTime; 21 | uint256 amount; 22 | } 23 | 24 | /// @dev the required authorizations for Staking and Distribution 25 | string[] private stakingMethods = [MSG_DELEGATE, MSG_UNDELEGATE, MSG_REDELEGATE]; 26 | string[] private distributionMethods = [MSG_WITHDRAW_DELEGATOR_REWARD]; 27 | /// @dev map to keep track of user deposits to the contract. 28 | mapping(address => uint256) public deposits; 29 | /// @dev map to keep track of the delegation amounts for a user. 30 | mapping(address => uint256) public delegations; 31 | /// @dev map that keeps track of winnings 32 | mapping(address => uint256) public winnings; 33 | /// @dev map that keeps track of all currently unbonding delegations 34 | mapping(address => UnbondingRequest) public unbondingDelegations; 35 | /// @dev the total amount staked. 36 | uint256 public totalStaked; 37 | /// @dev the totalStaked amount converted to total number of tickets. 38 | uint256 public totalTickets; 39 | /// @dev array of addresses for each user that has entered the lottery. 40 | address[] public participants; 41 | /// @dev map to keep track of addresses that have entered the lottery. 42 | mapping(address => bool) private addressExists; 43 | /// @dev the winners array stores all historical winners. 44 | Winner[] public winners; 45 | 46 | /// @dev events emitted by the contract. 47 | event Deposit(address indexed _from, uint256 _value); 48 | event Withdraw(address indexed _to, uint256 _value); 49 | event WithdrawWinnings(address indexed _to, uint256 _value); 50 | event EnterLottery(address indexed _from, uint256 _value); 51 | event ExitLottery(address indexed _to, uint256 _value); 52 | event PickWinner(address indexed _winner, uint256 _value); 53 | 54 | // Deposit into the contract 55 | function deposit() payable external { 56 | require(msg.value % 1 ether == 0, "Amount must be a whole number of Evmos"); 57 | deposits[msg.sender] += msg.value; 58 | emit Deposit(msg.sender, msg.value); 59 | } 60 | 61 | // Withdraw deposits from contract 62 | function withdraw(uint256 _amount) public { 63 | uint256 ts = uint256(int256(unbondingDelegations[msg.sender].completionTime)); 64 | require(block.timestamp >= ts, "The time has not passed yet"); 65 | require(unbondingDelegations[msg.sender].amount > 0, "You have nothing to withdraw"); 66 | deposits[msg.sender] += unbondingDelegations[msg.sender].amount; 67 | // Make sure that the sender has balance in our deposits map 68 | require(deposits[msg.sender] >= _amount, "Deposit amount larger than requested withdraw"); 69 | // Transfer the requested amount of Evmos to the sender. 70 | (bool sent,) = payable(msg.sender).call{value: _amount}(""); 71 | require(sent, "Failed to send Evmos"); 72 | delete unbondingDelegations[msg.sender]; 73 | emit Withdraw(msg.sender, _amount); 74 | } 75 | 76 | // Withdraw winnings from contract 77 | function withdrawWinnings() public { 78 | require(winnings[msg.sender] > 0, "You have no winnings yet"); 79 | (bool sent,) = payable(msg.sender).call{value: winnings[msg.sender]}(""); 80 | winnings[msg.sender] = 0; 81 | emit WithdrawWinnings(msg.sender, winnings[msg.sender]); 82 | } 83 | 84 | // Picks a winner for the lottery 85 | function pickWinner(string memory _validatorAddr) public { 86 | Coin[] memory newRewards = DISTRIBUTION_CONTRACT.withdrawDelegatorRewards(address(this), _validatorAddr); 87 | require(newRewards[0].amount > 0, "The rewards have not been distributed yet"); 88 | 89 | // Used to ensure that the order of the participants array is not used to determine the winner. 90 | _shuffleParticipants(); 91 | 92 | uint256 winnerIndex = getRandomNumber(); 93 | uint256 currentSum = 0; 94 | address winner; 95 | 96 | for (uint256 i = 0; i < participants.length; i++) { 97 | currentSum += delegations[participants[i]] / 1e18; 98 | if (currentSum >= winnerIndex) { 99 | winner = participants[i]; 100 | break; 101 | } 102 | } 103 | 104 | uint256 amountWon = newRewards[0].amount; 105 | winners.push(Winner(uint16(winners.length + 1), winnerIndex, winner, amountWon, block.timestamp)); 106 | winnings[winner] += amountWon; 107 | emit PickWinner(winner, amountWon); 108 | } 109 | 110 | // Enters the lottery by delegating to a validator 111 | function enterLottery(string memory _validatorAddr, uint256 _amount) public { 112 | require(_amount % 1 ether == 0, "Amount must be a whole number of Evmos"); 113 | require(_amount <= deposits[msg.sender], "This address does not hold a deposit amount with the lottery"); 114 | _approveRequiredMsgs(_amount); 115 | STAKING_CONTRACT.delegate(address(this), _validatorAddr, _amount); 116 | delegations[msg.sender] += _amount; 117 | deposits[msg.sender] -= _amount; 118 | totalStaked += _amount; 119 | totalTickets += _amount / 1e18; 120 | /// make sure an address is pushed only once per prize period 121 | if (!addressExists[msg.sender]) { 122 | participants.push(msg.sender); 123 | addressExists[msg.sender] = true; 124 | } 125 | emit EnterLottery(msg.sender, _amount); 126 | } 127 | 128 | // Exits the lottery returning the funds back to deposits after the unbonding period 129 | function exitLottery(string memory _validatorAddr, uint256 _amount) public { 130 | require(_amount <= delegations[msg.sender], "This address does not hold a delegation amount with the lottery"); 131 | require(_amount == delegations[msg.sender], "You must exit the entire delegation amount"); 132 | int64 completionTime = STAKING_CONTRACT.undelegate(address(this), _validatorAddr, _amount); 133 | delegations[msg.sender] -= _amount; 134 | unbondingDelegations[msg.sender] = UnbondingRequest(completionTime, _amount); 135 | totalStaked -= _amount; 136 | deposits[msg.sender] += _amount; 137 | totalTickets -= _amount / 1e18; 138 | 139 | if (delegations[msg.sender] == 0) { 140 | for (uint256 i = 0; i < participants.length; i++) { 141 | if (participants[i] == msg.sender) { 142 | participants[i] = participants[participants.length - 1]; 143 | participants.pop(); 144 | break; 145 | } 146 | } 147 | } 148 | 149 | emit ExitLottery(msg.sender, _amount); 150 | } 151 | 152 | 153 | // ------------------------------ 154 | // VIEW FUNCTIONS 155 | // ------------------------------ 156 | function getNumberOfRounds() public view returns (uint256){ 157 | return winners.length; 158 | } 159 | 160 | function getRandomNumber() public view returns (uint256) { 161 | uint256 randomNumber = uint256(keccak256(abi.encodePacked(block.timestamp, block.prevrandao, block.number))) % totalTickets; 162 | return randomNumber; 163 | } 164 | 165 | function getContractRewards(string memory _validatorAddr) public view returns (DecCoin[] memory) { 166 | return DISTRIBUTION_CONTRACT.delegationRewards(address(this), _validatorAddr); 167 | } 168 | 169 | function getDelegation(address _sender, string memory _valAddr) public view returns (uint256, Coin memory) { 170 | return STAKING_CONTRACT.delegation(_sender, _valAddr); 171 | } 172 | 173 | function getUnbondingDelegation(string memory _validatorAddr) public view returns (UnbondingDelegationEntry[] memory) { 174 | return STAKING_CONTRACT.unbondingDelegation(address(this), _validatorAddr); 175 | } 176 | 177 | function getBalance() public view returns (uint256) { 178 | return address(this).balance; 179 | } 180 | 181 | function getCurrentParticipants() public view returns (address[] memory) { 182 | return participants; 183 | } 184 | 185 | // ------------------------------ 186 | // HELPER FUNCTIONS 187 | // ------------------------------ 188 | 189 | /// @dev returns a random number between 0 and the number of participants 190 | function _random() private view returns (uint256) { 191 | uint256 randomNumber = uint256(keccak256(abi.encodePacked(block.timestamp, block.prevrandao, block.number))) % participants.length; 192 | return randomNumber; 193 | } 194 | 195 | /// @dev shuffles the participants array 196 | function _shuffleParticipants() private { 197 | for (uint256 i = participants.length - 1; i > 0; i--) { 198 | uint256 j = _random() % (i + 1); 199 | (participants[i], participants[j]) = (participants[j], participants[i]); 200 | } 201 | } 202 | 203 | /// @dev approves the staking and distribution contracts to spend the lottery's funds 204 | function _approveRequiredMsgs(uint256 _amount) internal { 205 | bool successStk = STAKING_CONTRACT.approve(address(this), _amount, stakingMethods); 206 | require(successStk, "Staking Approve failed"); 207 | } 208 | 209 | } 210 | -------------------------------------------------------------------------------- /examples/simple-ibc-transfer/README.md: -------------------------------------------------------------------------------- 1 | ## Simple IBC transfer 2 | 3 | This is a simple IBC transfer showcase using the ICS20 precompile interface. It sends EVMOS tokens 4 | from the Evmos blockchain to the Osmosis blockchain using the IBC transfer module. 5 | 6 | ## Approvals 7 | 8 | Before executing any IBC transfer related transactions, the user interacting with the smart contract must first approve 9 | any number of coins using the `Allocation` struct. The smart contract developer can choose to either separate 10 | the approval and execution of the IBC transfer or to combine them into a single transaction. 11 | -------------------------------------------------------------------------------- /examples/simple-ibc-transfer/contracts/ICS20Test.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: LGPL-3.0-only 2 | pragma solidity >=0.8.18; 3 | 4 | import "./ICS20.sol"; 5 | 6 | contract ICS20Test { 7 | 8 | // The constants for channel, port and base denom 9 | string private channel = "channel-0"; 10 | string private port = "transfer"; 11 | string private baseDenom = "aevmos"; 12 | 13 | // Default allowed list is empty indicating no restrictions 14 | string[] private defaultAllowList = new string[](0); 15 | 16 | // Sends coins to Osmosis chain via IBC transfer on the specified channel and port. 17 | function sendEvmosToOsmosis(uint256 _amount) public { 18 | // Approve only the amount to be send 19 | _approveTransfer(_amount); 20 | // Send IBC transfer using the interface function `transfer` 21 | ICS20_CONTRACT.transfer( 22 | port, 23 | channel, 24 | baseDenom, 25 | _amount, 26 | msg.sender, // The sender address 27 | "osmo1uqy7a69nv7qzjp6upcudxy00ykn6k0h59763ww", // The bech32 address of the receiver wallet on the Osmosis chain 28 | Height(1000, 1000), 29 | 0, 30 | "" // The memo field used for advanced functionality (blank here) 31 | ); 32 | } 33 | 34 | // Creates an approval allocation against the smart contract for IBC transfers. 35 | function _approveTransfer(uint256 _amount) public { 36 | // Create the spend limit of coins, in this case only aevmos 37 | Coin[] memory spendLimit = new Coin[](1); 38 | spendLimit[0] = Coin(baseDenom, _amount); 39 | // Create allocation for coins on the specified channel and port 40 | Allocation[] memory allocations = new Allocation[](1); 41 | allocations[0] = Allocation(port, channel, spendLimit, defaultAllowList); 42 | // Approve the contract address (grantee) for the specified allocations 43 | // The granter is always assumed to be the origin 44 | bool approved = ICS20_CONTRACT.approve(address(this), allocations); 45 | require(approved, "approval for IBC transfer failed"); 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /examples/simple-staker/README.md: -------------------------------------------------------------------------------- 1 | # Simple Staker 2 | 3 | This is an example of how to create a smart contract that directly calls the `Staking` and `Distribution` precompiled contracts - [Simple Staker](./contracts/SimpleStaker.sol) 4 | 5 | This smart contract allows the user to: 6 | 7 | - Stake tokens 8 | - Withdraw delegation rewards 9 | - Query current delegations 10 | - Query current delegations rewards 11 | 12 | The implementation is straightforward and is a good starting point for anyone who wants to create a smart contract that interacts with the Cosmos SDK. 13 | 14 | There are a couple of things to keep in mind when using the precompiled contracts: 15 | 16 | ## Approvals 17 | 18 | Before executing any transaction on the precompiled contracts, 19 | the user interacting with the smart contract must first approve these. 20 | In case of staking transactions, should specify the amount allowed. 21 | The smart contract developer can choose to either separate 22 | the approval and execution of the precompiled contracts transactions 23 | or to combine them into a single transaction. 24 | 25 | We have provided convenient constants - `MSG_DELEGATE`, `MSG_UNDELEGATE`, 26 | `MSG_REDELEGATE`, `MSG_CANCEL_UNDELEGATION`, `MSG_SET_WITHDRAWER_ADDRESS`, 27 | `MSG_WITHDRAW_DELEGATOR_REWARD`, `MSG_WITHDRAW_VALIDATOR_COMMISSION` - for easier use. 28 | 29 | This is done by calling the `approve` function and will create an authorization grant for the given Cosmos SDK message 30 | for the given spender address (this usually should be `address(this)` to approve the calling contract. 31 | 32 | Use the corresponding method when approving methods for each precompiled 33 | (e.g., use `STAKING_CONTRACT.approve(...)` for staking methods) 34 | The distribution contract does not require approvals. 35 | 36 | The [Simple Staker](./contracts/SimpleStaker.sol) has the function `approveRequiredMethods()` 37 | to perform the necessary approvals. 38 | It approves the required methods for staking tokens (`MSG_DELEGATE`) 39 | 40 | ## Allowances 41 | 42 | The `Staking` precompile will check if the message sender has enough allowance for the given message type and will 43 | return an error if the transaction exceeds the allowance. 44 | 45 | Decreasing the allowance after a successful transaction is not required since we handle it internally. 46 | 47 | ## Return Structs 48 | 49 | The precompiled contracts provide a set of structs that map to Cosmos SDK message returns types. 50 | 51 | These structs can be used as return types for smart contract functions or can be used to add further 52 | logic to your smart contracts. Once a transaction is executed, the return values can be used to verify the transaction 53 | was successful or be as inputs for additional logic. 54 | 55 | ## Failed Transactions 56 | 57 | The precompiled contracts provide verbose error messages for failed transactions. If a transaction fails, the state 58 | will not be persisted and the transaction will be reverted. 59 | -------------------------------------------------------------------------------- /examples/simple-staker/contracts/SimpleStaker.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: LGPL-v3 2 | pragma solidity >=0.8.17; 3 | 4 | import "../../../precompiles/stateful/Staking.sol"; 5 | import "../../../precompiles/stateful/Distribution.sol"; 6 | 7 | contract SimpleStaker { 8 | /// Methods to approve when calling approveRequiredMethods() 9 | string[] private stakingMethods = [MSG_DELEGATE]; 10 | 11 | /// @dev Approves the required transactions for delegation and withdrawal of staking rewards transactions. 12 | /// @dev This creates a Cosmos Authorization Grants for the given methods. 13 | /// @dev This emits an Approval event. 14 | function approveRequiredMethods() public { 15 | bool success = STAKING_CONTRACT.approve( 16 | address(this), 17 | type(uint256).max, 18 | stakingMethods 19 | ); 20 | require(success, "Failed to approve delegate method"); 21 | } 22 | 23 | /// @dev stake a given amount of tokens. 24 | /// @dev This emits an Delegate event. 25 | /// @param _validatorAddr The address of the validator. 26 | /// @param _amount The amount of tokens to stake in aevmos. 27 | function stakeTokens( 28 | string memory _validatorAddr, 29 | uint256 _amount 30 | ) public { 31 | bool success = STAKING_CONTRACT.delegate(msg.sender, _validatorAddr, _amount); 32 | require(success, "Failed to stake tokens"); 33 | } 34 | 35 | /// @dev withdraw delegation rewards from the specified validator address 36 | /// @dev This emits an WithdrawDelegatorRewards event. 37 | /// @param _validatorAddr The address of the validator. 38 | /// @return amount The amount of Coin withdrawn. 39 | function withdrawRewards( 40 | string memory _validatorAddr 41 | ) public returns (Coin[] memory amount) { 42 | return 43 | DISTRIBUTION_CONTRACT.withdrawDelegatorRewards( 44 | msg.sender, 45 | _validatorAddr 46 | ); 47 | } 48 | 49 | /// ================================ 50 | /// QUERIES 51 | /// ================================ 52 | 53 | /// @dev Returns the delegation information for a given validator for the msg sender. 54 | /// @param _validatorAddr The address of the validator. 55 | /// @return shares and balance. The delegation information for a given validator for the msg sender. 56 | function getDelegation( 57 | string memory _validatorAddr 58 | ) public view returns (uint256 shares, Coin memory balance) { 59 | return STAKING_CONTRACT.delegation(msg.sender, _validatorAddr); 60 | } 61 | 62 | /// @dev Returns the delegation rewards for a given validator for the msg sender. 63 | /// @param _validatorAddr The address of the validator. 64 | /// @return rewards The delegation rewards corresponding to the msg sender. 65 | function getDelegationRewards( 66 | string memory _validatorAddr 67 | ) public view returns (DecCoin[] memory rewards) { 68 | return 69 | DISTRIBUTION_CONTRACT.delegationRewards(msg.sender, _validatorAddr); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /examples/staking-manager/README.md: -------------------------------------------------------------------------------- 1 | # Staking Manager 2 | 3 | This is an example of how to create a smart contract that directly calls the `Staking` precompiled contract - [Staking Manager](./contracts/StakingManager.sol) 4 | 5 | The implementation is straightforward and is a good starting point for anyone who wants to create a smart contract that interacts with the Cosmos SDK. 6 | 7 | There are a couple of things to keep in mind when using the `Staking` precompile: 8 | 9 | ## Approvals 10 | 11 | Before executing any staking related transactions, the user interacting with the smart contract must first approve 12 | any number of staking transactions for with a specified amount. The smart contract developer can choose to either separate 13 | the approval and execution of the staking transaction or to combine them into a single transaction. 14 | 15 | We have provided convenient constants - `MSG_DELEGATE`, `MSG_UNDELEGATE`, `MSG_REDELEGATE`, `MSG_CANCEL_UNDELEGATION` for easier use. 16 | 17 | This is done by calling the `approve` function and will create an authorization grant for the given Cosmos SDK message 18 | for the given spender address (this usually should be `address(this)` to approve the calling contract. 19 | 20 | ## Allowances 21 | 22 | The `Staking` precompile will check if the message sender has enough allowance for the given message type and will 23 | return an error if the transaction exceeds the allowance. 24 | 25 | Decreasing the allowance after a successful transaction is not required since we handle it internally. 26 | 27 | ## Return Structs 28 | 29 | The `Staking` precompile provides a set of structs that map to Cosmos SDK message returns types. 30 | 31 | These structs can be used as return types for smart contract functions or can be used to add further 32 | logic to your smart contracts. Once a transaction is executed, the return values can be used to verify the transaction 33 | was successful or be as inputs for additional logic. 34 | 35 | ## Failed Transactions 36 | 37 | The `Staking` precompile provides verbose error messages for failed transactions. If a transaction fails, the state 38 | will not be persisted and the transaction will be reverted. 39 | -------------------------------------------------------------------------------- /examples/staking-manager/contracts/StakingManager.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: LGPL-v3 2 | pragma solidity >=0.8.17; 3 | 4 | import "../../../precompiles/stateful/Staking.sol"; 5 | 6 | contract StakingManager { 7 | string[] private stakingMethods = [MSG_DELEGATE, MSG_UNDELEGATE, MSG_REDELEGATE, MSG_CANCEL_UNDELEGATION]; 8 | 9 | /// @dev Approves all staking transactions with the maximum amount of tokens. 10 | /// @dev This creates a Cosmos Authorization Grant for the given methods. 11 | /// @dev This emits an Approval event. 12 | function approveAllStakingMethodsWithMaxAmount() public { 13 | bool success = STAKING_CONTRACT.approve(address(this), type(uint256).max, stakingMethods); 14 | require(success, "Failed to approve staking methods"); 15 | } 16 | 17 | /// @dev Approves a list of Cosmos staking transactions with a specific amount of tokens denominated in aevmos. 18 | /// @dev This creates a Cosmos Authorization Grant for the given methods. 19 | /// @dev This emits an Approval event. 20 | /// @param _methods The message type URLs of the methods to approve. 21 | /// @param _amount The amount of tokens approved to be spent in aevmos. 22 | function approveStakingMethods(string[] calldata _methods, uint256 _amount) public { 23 | bool success = STAKING_CONTRACT.approve(address(this), _amount, _methods); 24 | require(success, "Failed to approve staking methods"); 25 | } 26 | 27 | /// @dev Returns the remaining number of tokens that spender will be allowed to spend 28 | /// on behalf of the owner through staking. This is zero by default. 29 | /// @return remaining The remaining number of tokens available to be spent in aevmos. 30 | function getAllowance() public view returns (uint256 remaining) { 31 | return STAKING_CONTRACT.allowance(address(this), msg.sender, MSG_DELEGATE); 32 | } 33 | 34 | /// @dev stake a given amount of tokens. Returns the completion time of the staking transaction. 35 | /// @dev This emits an Delegate event. 36 | /// @param _validatorAddr The address of the validator. 37 | /// @param _amount The amount of tokens to stake in aevmos. 38 | /// @return completionTime The completion time of the staking transaction. 39 | function stakeTokens(string memory _validatorAddr, uint256 _amount) public returns (int64 completionTime) { 40 | return STAKING_CONTRACT.delegate(msg.sender, _validatorAddr, _amount); 41 | } 42 | 43 | /// @dev redelegate a given amount of tokens. Returns the completion time of the redelegate transaction. 44 | /// @dev This emits a Redelegate event. 45 | /// @param _validatorSrcAddr The address of the source validator. 46 | /// @param _validatorDstAddr The address of the destination validator. 47 | /// @param _amount The amount of tokens to redelegate in aevmos. 48 | /// @return completionTime The completion time of the redelegate transaction. 49 | function redelegateTokens(string memory _validatorSrcAddr, string memory _validatorDstAddr, uint256 _amount) public returns (int64 completionTime) { 50 | return STAKING_CONTRACT.redelegate(msg.sender, _validatorSrcAddr, _validatorDstAddr, _amount); 51 | } 52 | 53 | /// @dev unstake a given amount of tokens. Returns the completion time of the unstaking transaction. 54 | /// @dev This emits an Undelegate event. 55 | /// @param _validatorAddr The address of the validator. 56 | /// @param _amount The amount of tokens to unstake in aevmos. 57 | /// @return completionTime The completion time of the unstaking transaction. 58 | function unstakeTokens(string memory _validatorAddr, uint256 _amount) public returns (int64 completionTime) { 59 | return STAKING_CONTRACT.undelegate(msg.sender, _validatorAddr, _amount); 60 | } 61 | 62 | /// @dev cancel an unbonding delegation. Returns the completion time of the unbonding delegation cancellation transaction. 63 | /// @dev This emits an CancelUnbondingDelegation event. 64 | /// @param _validatorAddr The address of the validator. 65 | /// @param _amount The amount of tokens to cancel the unbonding delegation in aevmos. 66 | /// @param _creationHeight The creation height of the unbonding delegation. 67 | function cancelUnbondingDelegation(string memory _validatorAddr, uint256 _amount, uint256 _creationHeight) public returns (int64 completionTime) { 68 | return STAKING_CONTRACT.cancelUnbondingDelegation(msg.sender, _validatorAddr, _amount, _creationHeight); 69 | } 70 | 71 | /// @dev Returns the delegation information for a given validator for the msg sender. 72 | /// @param _validatorAddr The address of the validator. 73 | /// @return shares and balance. The delegation information for a given validator for the msg sender. 74 | function getDelegation(string memory _validatorAddr) public view returns (uint256 shares, Coin memory balance) { 75 | return STAKING_CONTRACT.delegation(msg.sender, _validatorAddr); 76 | } 77 | 78 | /// @dev Returns the unbonding delegation information for a given validator for the msg sender. 79 | /// @param _validatorAddr The address of the validator. 80 | /// @return entries The unbonding delegation entries for a given validator for the msg sender. 81 | function getUnbondingDelegation(string memory _validatorAddr) public view returns (UnbondingDelegationEntry[] memory entries) { 82 | return STAKING_CONTRACT.unbondingDelegation(msg.sender, _validatorAddr); 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /outposts/osmosis/README.md: -------------------------------------------------------------------------------- 1 | # Osmosis Cross Chain Swap (XCS) Outpost 2 | 3 | ## Overview 4 | 5 | The following is an example Osmosis Outpost smart contract that interacts with the 6 | [Osmosis Cross Chain Swap contract](https://github.com/osmosis-labs/osmosis/tree/be63fb58580b87808f6d7ed9523a43e976899258/cosmwasm/contracts/crosschain-swaps), 7 | and specifically version 1 of the contract for the [**Native to Osmosis Native swap**](https://github.com/osmosis-labs/osmosis/tree/main/cosmwasm/contracts/crosschain-swaps#non-native-to-non-native). 8 | This contract can be deployed as a standalone contract and called 9 | from other contracts or you can include this logic 10 | into your own contract. In this case you can swap Evmos for Osmosis tokens 11 | and receive them back on the Evmos chain. 12 | This functionality is available only for the latest Evmos and Osmosis testnets. 13 | 14 | ## How it works 15 | 16 | ### Osmosis 17 | 18 | The Osmosis Outpost contract is a CosmWasm contract deployed on the Osmosis chain. 19 | It consists of two separate contracts: 20 | 21 | - [crosschain_swaps](https://celatone.osmosis.zone/testnet/contracts/osmo1ye7nsslrgwc6ngmav67h26zckg8wjeay4agnlzke66f8apq3ls8sqednc4) - 22 | this contract checks for a correct `memo` field and routes to the `swaprouter` contract. 23 | - [swaprouter](https://celatone.osmosis.zone/testnet/contracts/osmo1cr8pd93vrw236jqr696p23k0g37dzkegjjf9884023ts48yazxhsj38hlv) - 24 | the swap router performs the actual swap. It requires a configuration for the pools a user wants to use to swap. 25 | 26 | ## Evmos 27 | 28 | On Evmos all you need to do is call the swapping function on the `XSCOutpost` contract, the memo field is constructed, 29 | automatically using the helper function. You will be sending `atevmos` and in return receive `osmo` tokens which will have 30 | an ibc voucher denom of: `ibc/95AEB3C077D1E35BA2AA79E338EB5B703C835C804127F7CC4942C8F23F710B26` 31 | 32 | ## Testnet 33 | 34 | This contract is configured for testnet and would **NOT** work on mainnet without changing the configurations. 35 | The channel id, contract address and pool ids are all testnet specific. 36 | For mainnet this document and the contract will be updated with the correct values. 37 | 38 | **NOTE** - Moreover the [evmos/osmo pool 48](https://testnet.osmosis.zone/pool/48) was setup in a way that 1 aevmos = 1 osmo. 39 | On mainnet this will not be the case as it will take into consideration the different token precisions and the swap will be adjusted. 40 | On mainnet: evmos token precision = 18, osmo token precision = 6. 41 | 42 | ## Mainnet 43 | 44 | TODO 45 | 46 | ## Disclaimer 47 | 48 | This contract is not yet audited and is considered experimental. 49 | Use at your own risk. 50 | -------------------------------------------------------------------------------- /outposts/osmosis/XCSOutpost.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: LGPL-3.0-only 2 | pragma solidity >=0.8.17; 3 | 4 | import ".../../../precompiles/stateful/ICS20.sol"; 5 | import "../../precompiles/common/Types.sol"; 6 | 7 | 8 | contract XCSOutpost { 9 | 10 | /// @dev The constants for channel, port and base denom 11 | string private channel = "channel-215"; 12 | string private port = "transfer"; 13 | string private XCS_CONTRACT = "osmo1a34wxsxjwvtz3ua4hnkh4lv3d4qrgry0fhkasppplphwu5k538tqcyms9x"; 14 | 15 | /// @dev Default allowed list is empty indicating no restrictions 16 | string[] private defaultAllowList = new string[](0); 17 | 18 | /// @dev Creates an approval allocation against the smart contract for IBC transfers. 19 | function _approveTransfer(uint256 _amount, string calldata _baseDenom) private { 20 | // Create the spend limit of coins, in this case only aevmos 21 | Coin[] memory spendLimit = new Coin[](1); 22 | spendLimit[0] = Coin(_baseDenom, _amount); 23 | // Create allocation for coins on the specified channel and port 24 | ICS20Allocation[] memory allocations = new ICS20Allocation[](1); 25 | allocations[0] = ICS20Allocation(port, channel, spendLimit, defaultAllowList); 26 | // Approve the contract address (grantee) for the specified allocations 27 | // The granter is always assumed to be the origin 28 | bool approved = ICS20_CONTRACT.approve(address(this), allocations); 29 | require(approved, "approval for IBC transfer failed"); 30 | } 31 | 32 | 33 | /// @dev Preparation of memo field for cross chain swap for case 4 - Native (atevmos) to Osmosis Native (uosmo) 34 | /// @param _output_denom The target denomination to be swapped for, e.g. "uosmo" 35 | /// @param _receiver The address bech32 string receiving the swapped funds 36 | function nativeToOsmoNativeMemo(string memory _output_denom, string memory _receiver) public view returns (string memory) { 37 | string memory memo = string(abi.encodePacked( 38 | '{', 39 | '"wasm": {', 40 | '"contract": "', XCS_CONTRACT, '",', 41 | '"msg": {', 42 | '"osmosis_swap": {', 43 | '"output_denom": "', _output_denom, '",', 44 | '"slippage": {', 45 | '"twap": {', 46 | '"slippage_percentage": "10",', 47 | '"window_seconds": 30', 48 | '}', 49 | '},', 50 | '"receiver": "', _receiver, '",', 51 | '"on_failed_delivery": "do_nothing"', 52 | '}', 53 | '}', 54 | '}', 55 | '}' 56 | )); 57 | 58 | return memo; 59 | 60 | } 61 | 62 | // @dev The main Swap function which will swap a base denom for an output denom using the native to osmosis native case 63 | // @param _amount The amount of the base denomination to be swapped 64 | // @param _baseDenom The base denomination used for the swap, e.g. "atevmos" for Evmos testnet 65 | // @param _outputDenom The target denomination to be swapped for, e.g. "uosmo" 66 | // @param _receiver The address bech32 string receiving the swapped funds 67 | function osmosisSwap(uint256 _amount, string calldata _baseDenom, string calldata _outputDenom, string calldata _receiver) public { 68 | _approveTransfer(_amount, _baseDenom); 69 | Height memory timeoutHeight = Height(100,100); 70 | string memory memo = nativeToOsmoNativeMemo(_outputDenom, _receiver); 71 | 72 | ICS20_CONTRACT.transfer( 73 | port, 74 | channel, 75 | _baseDenom, 76 | _amount, 77 | msg.sender, 78 | XCS_CONTRACT, // The cross chain swaps CosmWasm contract 79 | timeoutHeight, 80 | 0, 81 | memo 82 | ); 83 | } 84 | } -------------------------------------------------------------------------------- /outposts/stride/LiquidStakeOutpost.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: LGPL-3.0-only 2 | pragma solidity >=0.8.17; 3 | 4 | import ".../../../precompiles/stateful/ICS20.sol"; 5 | import "../../precompiles/common/Types.sol"; 6 | 7 | contract StrideOutpost { 8 | 9 | // The constants for channel and port 10 | string private channel = "channel-25"; 11 | string private port = "transfer"; 12 | string private baseDenom = "aevmos"; 13 | string private stDenom = "ibc/C9364B2C453F0428D04FD40B6CF486BA138FA462FE43A116268A7B695AFCFE7F"; // The IBC denom of stAevmos 14 | 15 | // Default allowed list is empty indicating no restrictions 16 | string[] private defaultAllowList = new string[](0); 17 | 18 | /// @dev Creates an approval allocation against the smart contract for IBC transfers. 19 | /// @param _amount The amount of the base denomination to be swapped 20 | /// @param _baseDenom The base denomination used for the swap, e.g. "aevmos" for Evmos mainnet 21 | function _approveTransfer(uint256 _amount, string memory _baseDenom) private { 22 | // Create the spend limit of coins, in this case only aevmos 23 | Coin[] memory spendLimit = new Coin[](1); 24 | spendLimit[0] = Coin(_baseDenom, _amount); 25 | // Create allocation for coins on the specified channel and port 26 | ICS20Allocation[] memory allocations = new ICS20Allocation[](1); 27 | allocations[0] = ICS20Allocation(port, channel, spendLimit, defaultAllowList); 28 | // Approve the contract address (grantee) for the specified allocations 29 | // The granter is always assumed to be the origin 30 | bool approved = ICS20_CONTRACT.approve(address(this), allocations); 31 | require(approved, "approval for IBC transfer failed"); 32 | } 33 | 34 | /// @dev Builds a liquid staking memo that can parsed by the stride chain to trigger a liquid staking action 35 | /// @param _strideReceiver the bech32 address of the receiver on the Stride chain 36 | /// @param _evmosReceiver the bech32 address of the receiver on Evmos 37 | function buildLiquidStakeMemo(string memory _strideReceiver, string memory _evmosReceiver) public pure returns (string memory) { 38 | string memory memo = string(abi.encodePacked( 39 | '{', 40 | '"autopilot": {', 41 | '"receiver": "', _strideReceiver, '",', 42 | '"stakeibc": {', 43 | '"ibc_receiver":"', _evmosReceiver, '",', 44 | '"action": "LiquidStake"', 45 | '}', 46 | '}', 47 | '}' 48 | )); 49 | 50 | return memo; 51 | } 52 | 53 | /// @dev Builds the redeem memo that can be parsed by the stride chain to trigger the redeem action 54 | /// @param _strideReceiver the bech32 address of the receiver on the Stride chain 55 | /// @param _evmosReceiver the bech32 address of the receiver on Evmos 56 | function buildRedeemMemo(string memory _strideReceiver, string memory _evmosReceiver) public pure returns (string memory) { 57 | string memory memo = string(abi.encodePacked( 58 | '{', 59 | '"autopilot": {', 60 | '"receiver": "', _strideReceiver, '",', 61 | '"stakeibc": {', 62 | '"transfer_channel": "channel-9"', 63 | '"ibc_receiver":"', _evmosReceiver, '",', 64 | '"action": "RedeemStake"', 65 | '}', 66 | '}', 67 | '}' 68 | )); 69 | 70 | return memo; 71 | } 72 | 73 | /// @dev Transfers the specified amount of "aevmos" to the specified receiver on the Stride chain 74 | /// with the correct memo to trigger a liquid staking action. 75 | /// NOTE - on testnet the base denom will be "atevmos" 76 | /// @param _amount The amount of "aevmos" to be swapped 77 | /// @param _strideReceiver The bech32 address of the receiver on the Stride chain 78 | /// @param _evmosReceiver The bech32 address of the receiver on the Stride chain 79 | function liquidStakeEvmos(uint256 _amount, string memory _strideReceiver, string memory _evmosReceiver) public { 80 | _approveTransfer(_amount, baseDenom); 81 | Height memory timeoutHeight = Height(100,100); 82 | string memory memo = buildLiquidStakeMemo(_strideReceiver, _evmosReceiver); 83 | 84 | ICS20_CONTRACT.transfer( 85 | port, 86 | channel, 87 | baseDenom, 88 | _amount, 89 | msg.sender, 90 | _strideReceiver, 91 | timeoutHeight, 92 | 0, 93 | memo 94 | ); 95 | } 96 | 97 | /// @dev Transfers the specified amount of "staevmos" to the specified receiver on the Stride chain 98 | /// with the correct memo to trigger a redeem stake action. 99 | /// @param _amount The amount of "stEvmos" to be redeemed 100 | /// @param _strideReceiver The bech32 address of the receiver on the Stride chain 101 | /// @param _evmosReceiver The bech32 address of the receiver on the Stride chain 102 | function redeemStEvmos(uint256 _amount, string memory _strideReceiver, string memory _evmosReceiver) public { 103 | _approveTransfer(_amount, stDenom); 104 | Height memory timeoutHeight = Height(100,100); 105 | string memory memo = buildRedeemMemo(_strideReceiver, _evmosReceiver); 106 | 107 | ICS20_CONTRACT.transfer( 108 | port, 109 | channel, 110 | stDenom, 111 | _amount, 112 | msg.sender, 113 | _strideReceiver, 114 | timeoutHeight, 115 | 0, 116 | memo 117 | ); 118 | } 119 | } -------------------------------------------------------------------------------- /outposts/stride/README.md: -------------------------------------------------------------------------------- 1 | # Stride Liquid Stake Outpost 2 | 3 | ## Overview 4 | 5 | The following is an example Stride Outpost smart contract that interacts with the 6 | [Autopilot](https://github.com/Stride-Labs/stride/tree/main/x/autopilot) feature on the Stride chain. 7 | Its purpose is to liquid stake assets like Evmos by directly calling a smart contract. 8 | 9 | ## Mainnet 10 | 11 | The following contract is configured for mainnet and would **NOT** work 12 | on testnet without changing the configurations located at the top of the contract. 13 | 14 | ```solidity 15 | // The constants for channel and port for testnet 16 | string private channel = "channel-25"; 17 | string private port = "transfer"; 18 | string private baseDenom = "aevmos"; 19 | // The IBC denom of statevmos 20 | string private stDenom = "ibc/C9364B2C453F0428D04FD40B6CF486BA138FA462FE43A116268A7B695AFCFE7F"; 21 | ``` 22 | 23 | ## How it works 24 | 25 | The Autopilot feature is a middleware that triggers an action on the Stride chain 26 | based on `memo` field of an IBC transfer transaction. We build this memo field so 27 | devs have a simple way to trigger actions on the Stride chain. 28 | 29 | ### Constants 30 | 31 | This contract has the following constants: 32 | - `channel` - the IBC channel on Evmos for Stride - `channel-25` 33 | - `port` - The IBC port for the transfer - `transfer` 34 | - `baseDenom` - The base denom we are sending to the Stride chain - `aevmos` 35 | - `stDenom` - The IBC denom representation of Evmos for `stAevmos` 36 | 37 | ### Functions 38 | 39 | - `liquidStakeEvmos` - this is the main function of the Outpost, it requires an `amount` and `receiver` 40 | - `_amount` - the amount of `aevmos` to liquid stake 41 | - `_strideReceiver` - the bech32 address of the receiver on the Stride chain, this can usually be found in Keplr 42 | or the Stride dashboard 43 | - `_evmosReceiver` - the bech32 address of the receiver on the Evmos chain. This can be any address. 44 | 45 | - `redeemStEvmos` - this function redeems `stAevmos` for `aevmos`. 46 | - `_amount` - the amount of `stAevmos` to redeem 47 | - `_strideReceiver` - the bech32 address of the receiver on the Stride chain, this can usually be found in Keplr 48 | or the Stride dashboard 49 | - `_evmosReceiver` - the bech32 address of the receiver on the Evmos chain. This can be any address. 50 | -------------------------------------------------------------------------------- /precompiles/abi/authorization.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "anonymous": false, 4 | "inputs": [ 5 | { 6 | "indexed": true, 7 | "internalType": "address", 8 | "name": "owner", 9 | "type": "address" 10 | }, 11 | { 12 | "indexed": true, 13 | "internalType": "address", 14 | "name": "spender", 15 | "type": "address" 16 | }, 17 | { 18 | "indexed": false, 19 | "internalType": "string[]", 20 | "name": "methods", 21 | "type": "string[]" 22 | }, 23 | { 24 | "indexed": false, 25 | "internalType": "uint256[]", 26 | "name": "values", 27 | "type": "uint256[]" 28 | } 29 | ], 30 | "name": "AllowanceChange", 31 | "type": "event" 32 | }, 33 | { 34 | "anonymous": false, 35 | "inputs": [ 36 | { 37 | "indexed": true, 38 | "internalType": "address", 39 | "name": "owner", 40 | "type": "address" 41 | }, 42 | { 43 | "indexed": true, 44 | "internalType": "address", 45 | "name": "spender", 46 | "type": "address" 47 | }, 48 | { 49 | "indexed": false, 50 | "internalType": "string[]", 51 | "name": "methods", 52 | "type": "string[]" 53 | }, 54 | { 55 | "indexed": false, 56 | "internalType": "uint256", 57 | "name": "value", 58 | "type": "uint256" 59 | } 60 | ], 61 | "name": "Approval", 62 | "type": "event" 63 | }, 64 | { 65 | "inputs": [ 66 | { 67 | "internalType": "address", 68 | "name": "owner", 69 | "type": "address" 70 | }, 71 | { 72 | "internalType": "address", 73 | "name": "spender", 74 | "type": "address" 75 | }, 76 | { 77 | "internalType": "string", 78 | "name": "method", 79 | "type": "string" 80 | } 81 | ], 82 | "name": "allowance", 83 | "outputs": [ 84 | { 85 | "internalType": "uint256", 86 | "name": "remaining", 87 | "type": "uint256" 88 | } 89 | ], 90 | "stateMutability": "view", 91 | "type": "function" 92 | }, 93 | { 94 | "inputs": [ 95 | { 96 | "internalType": "address", 97 | "name": "spender", 98 | "type": "address" 99 | }, 100 | { 101 | "internalType": "uint256", 102 | "name": "amount", 103 | "type": "uint256" 104 | }, 105 | { 106 | "internalType": "string[]", 107 | "name": "methods", 108 | "type": "string[]" 109 | } 110 | ], 111 | "name": "approve", 112 | "outputs": [ 113 | { 114 | "internalType": "bool", 115 | "name": "approved", 116 | "type": "bool" 117 | } 118 | ], 119 | "stateMutability": "nonpayable", 120 | "type": "function" 121 | }, 122 | { 123 | "inputs": [ 124 | { 125 | "internalType": "address", 126 | "name": "spender", 127 | "type": "address" 128 | }, 129 | { 130 | "internalType": "uint256", 131 | "name": "amount", 132 | "type": "uint256" 133 | }, 134 | { 135 | "internalType": "string[]", 136 | "name": "methods", 137 | "type": "string[]" 138 | } 139 | ], 140 | "name": "decreaseAllowance", 141 | "outputs": [ 142 | { 143 | "internalType": "bool", 144 | "name": "approved", 145 | "type": "bool" 146 | } 147 | ], 148 | "stateMutability": "nonpayable", 149 | "type": "function" 150 | }, 151 | { 152 | "inputs": [ 153 | { 154 | "internalType": "address", 155 | "name": "spender", 156 | "type": "address" 157 | }, 158 | { 159 | "internalType": "uint256", 160 | "name": "amount", 161 | "type": "uint256" 162 | }, 163 | { 164 | "internalType": "string[]", 165 | "name": "methods", 166 | "type": "string[]" 167 | } 168 | ], 169 | "name": "increaseAllowance", 170 | "outputs": [ 171 | { 172 | "internalType": "bool", 173 | "name": "approved", 174 | "type": "bool" 175 | } 176 | ], 177 | "stateMutability": "nonpayable", 178 | "type": "function" 179 | } 180 | ] 181 | -------------------------------------------------------------------------------- /precompiles/abi/bech32.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "inputs": [ 4 | { 5 | "internalType": "string", 6 | "name": "bech32Address", 7 | "type": "string" 8 | } 9 | ], 10 | "name": "bech32ToHex", 11 | "outputs": [ 12 | { 13 | "internalType": "address", 14 | "name": "addr", 15 | "type": "address" 16 | } 17 | ], 18 | "stateMutability": "nonpayable", 19 | "type": "function" 20 | }, 21 | { 22 | "inputs": [ 23 | { 24 | "internalType": "address", 25 | "name": "addr", 26 | "type": "address" 27 | }, 28 | { 29 | "internalType": "string", 30 | "name": "prefix", 31 | "type": "string" 32 | } 33 | ], 34 | "name": "hexToBech32", 35 | "outputs": [ 36 | { 37 | "internalType": "string", 38 | "name": "bech32Address", 39 | "type": "string" 40 | } 41 | ], 42 | "stateMutability": "nonpayable", 43 | "type": "function" 44 | } 45 | ] 46 | -------------------------------------------------------------------------------- /precompiles/abi/distribution.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "anonymous": false, 4 | "inputs": [ 5 | { 6 | "indexed": true, 7 | "internalType": "address", 8 | "name": "caller", 9 | "type": "address" 10 | }, 11 | { 12 | "indexed": false, 13 | "internalType": "string", 14 | "name": "withdrawerAddress", 15 | "type": "string" 16 | } 17 | ], 18 | "name": "SetWithdrawerAddress", 19 | "type": "event" 20 | }, 21 | { 22 | "anonymous": false, 23 | "inputs": [ 24 | { 25 | "indexed": true, 26 | "internalType": "address", 27 | "name": "delegatorAddress", 28 | "type": "address" 29 | }, 30 | { 31 | "indexed": true, 32 | "internalType": "string", 33 | "name": "validatorAddress", 34 | "type": "string" 35 | }, 36 | { 37 | "indexed": false, 38 | "internalType": "uint256", 39 | "name": "amount", 40 | "type": "uint256" 41 | } 42 | ], 43 | "name": "WithdrawDelegatorRewards", 44 | "type": "event" 45 | }, 46 | { 47 | "anonymous": false, 48 | "inputs": [ 49 | { 50 | "indexed": true, 51 | "internalType": "string", 52 | "name": "validatorAddress", 53 | "type": "string" 54 | }, 55 | { 56 | "indexed": false, 57 | "internalType": "uint256", 58 | "name": "commission", 59 | "type": "uint256" 60 | } 61 | ], 62 | "name": "WithdrawValidatorCommission", 63 | "type": "event" 64 | }, 65 | { 66 | "inputs": [ 67 | { 68 | "internalType": "address", 69 | "name": "delegatorAddress", 70 | "type": "address" 71 | }, 72 | { 73 | "internalType": "string", 74 | "name": "validatorAddress", 75 | "type": "string" 76 | } 77 | ], 78 | "name": "delegationRewards", 79 | "outputs": [ 80 | { 81 | "components": [ 82 | { 83 | "internalType": "string", 84 | "name": "denom", 85 | "type": "string" 86 | }, 87 | { 88 | "internalType": "uint256", 89 | "name": "amount", 90 | "type": "uint256" 91 | }, 92 | { 93 | "internalType": "uint8", 94 | "name": "precision", 95 | "type": "uint8" 96 | } 97 | ], 98 | "internalType": "struct DecCoin[]", 99 | "name": "rewards", 100 | "type": "tuple[]" 101 | } 102 | ], 103 | "stateMutability": "view", 104 | "type": "function" 105 | }, 106 | { 107 | "inputs": [ 108 | { 109 | "internalType": "address", 110 | "name": "delegatorAddress", 111 | "type": "address" 112 | } 113 | ], 114 | "name": "delegationTotalRewards", 115 | "outputs": [ 116 | { 117 | "components": [ 118 | { 119 | "internalType": "string", 120 | "name": "validatorAddress", 121 | "type": "string" 122 | }, 123 | { 124 | "components": [ 125 | { 126 | "internalType": "string", 127 | "name": "denom", 128 | "type": "string" 129 | }, 130 | { 131 | "internalType": "uint256", 132 | "name": "amount", 133 | "type": "uint256" 134 | }, 135 | { 136 | "internalType": "uint8", 137 | "name": "precision", 138 | "type": "uint8" 139 | } 140 | ], 141 | "internalType": "struct DecCoin[]", 142 | "name": "reward", 143 | "type": "tuple[]" 144 | } 145 | ], 146 | "internalType": "struct DelegationDelegatorReward[]", 147 | "name": "rewards", 148 | "type": "tuple[]" 149 | }, 150 | { 151 | "components": [ 152 | { 153 | "internalType": "string", 154 | "name": "denom", 155 | "type": "string" 156 | }, 157 | { 158 | "internalType": "uint256", 159 | "name": "amount", 160 | "type": "uint256" 161 | }, 162 | { 163 | "internalType": "uint8", 164 | "name": "precision", 165 | "type": "uint8" 166 | } 167 | ], 168 | "internalType": "struct DecCoin[]", 169 | "name": "total", 170 | "type": "tuple[]" 171 | } 172 | ], 173 | "stateMutability": "view", 174 | "type": "function" 175 | }, 176 | { 177 | "inputs": [ 178 | { 179 | "internalType": "address", 180 | "name": "delegatorAddress", 181 | "type": "address" 182 | } 183 | ], 184 | "name": "delegatorValidators", 185 | "outputs": [ 186 | { 187 | "internalType": "string[]", 188 | "name": "validators", 189 | "type": "string[]" 190 | } 191 | ], 192 | "stateMutability": "view", 193 | "type": "function" 194 | }, 195 | { 196 | "inputs": [ 197 | { 198 | "internalType": "address", 199 | "name": "delegatorAddress", 200 | "type": "address" 201 | } 202 | ], 203 | "name": "delegatorWithdrawAddress", 204 | "outputs": [ 205 | { 206 | "internalType": "string", 207 | "name": "withdrawAddress", 208 | "type": "string" 209 | } 210 | ], 211 | "stateMutability": "view", 212 | "type": "function" 213 | }, 214 | { 215 | "inputs": [ 216 | { 217 | "internalType": "address", 218 | "name": "delegatorAddress", 219 | "type": "address" 220 | }, 221 | { 222 | "internalType": "string", 223 | "name": "withdrawerAddress", 224 | "type": "string" 225 | } 226 | ], 227 | "name": "setWithdrawAddress", 228 | "outputs": [ 229 | { 230 | "internalType": "bool", 231 | "name": "success", 232 | "type": "bool" 233 | } 234 | ], 235 | "stateMutability": "nonpayable", 236 | "type": "function" 237 | }, 238 | { 239 | "inputs": [ 240 | { 241 | "internalType": "string", 242 | "name": "validatorAddress", 243 | "type": "string" 244 | } 245 | ], 246 | "name": "validatorCommission", 247 | "outputs": [ 248 | { 249 | "components": [ 250 | { 251 | "internalType": "string", 252 | "name": "denom", 253 | "type": "string" 254 | }, 255 | { 256 | "internalType": "uint256", 257 | "name": "amount", 258 | "type": "uint256" 259 | }, 260 | { 261 | "internalType": "uint8", 262 | "name": "precision", 263 | "type": "uint8" 264 | } 265 | ], 266 | "internalType": "struct DecCoin[]", 267 | "name": "commission", 268 | "type": "tuple[]" 269 | } 270 | ], 271 | "stateMutability": "view", 272 | "type": "function" 273 | }, 274 | { 275 | "inputs": [ 276 | { 277 | "internalType": "string", 278 | "name": "validatorAddress", 279 | "type": "string" 280 | } 281 | ], 282 | "name": "validatorDistributionInfo", 283 | "outputs": [ 284 | { 285 | "components": [ 286 | { 287 | "internalType": "string", 288 | "name": "operatorAddress", 289 | "type": "string" 290 | }, 291 | { 292 | "components": [ 293 | { 294 | "internalType": "string", 295 | "name": "denom", 296 | "type": "string" 297 | }, 298 | { 299 | "internalType": "uint256", 300 | "name": "amount", 301 | "type": "uint256" 302 | }, 303 | { 304 | "internalType": "uint8", 305 | "name": "precision", 306 | "type": "uint8" 307 | } 308 | ], 309 | "internalType": "struct DecCoin[]", 310 | "name": "selfBondRewards", 311 | "type": "tuple[]" 312 | }, 313 | { 314 | "components": [ 315 | { 316 | "internalType": "string", 317 | "name": "denom", 318 | "type": "string" 319 | }, 320 | { 321 | "internalType": "uint256", 322 | "name": "amount", 323 | "type": "uint256" 324 | }, 325 | { 326 | "internalType": "uint8", 327 | "name": "precision", 328 | "type": "uint8" 329 | } 330 | ], 331 | "internalType": "struct DecCoin[]", 332 | "name": "commission", 333 | "type": "tuple[]" 334 | } 335 | ], 336 | "internalType": "struct ValidatorDistributionInfo", 337 | "name": "distributionInfo", 338 | "type": "tuple" 339 | } 340 | ], 341 | "stateMutability": "view", 342 | "type": "function" 343 | }, 344 | { 345 | "inputs": [ 346 | { 347 | "internalType": "string", 348 | "name": "validatorAddress", 349 | "type": "string" 350 | } 351 | ], 352 | "name": "validatorOutstandingRewards", 353 | "outputs": [ 354 | { 355 | "components": [ 356 | { 357 | "internalType": "string", 358 | "name": "denom", 359 | "type": "string" 360 | }, 361 | { 362 | "internalType": "uint256", 363 | "name": "amount", 364 | "type": "uint256" 365 | }, 366 | { 367 | "internalType": "uint8", 368 | "name": "precision", 369 | "type": "uint8" 370 | } 371 | ], 372 | "internalType": "struct DecCoin[]", 373 | "name": "rewards", 374 | "type": "tuple[]" 375 | } 376 | ], 377 | "stateMutability": "view", 378 | "type": "function" 379 | }, 380 | { 381 | "inputs": [ 382 | { 383 | "internalType": "string", 384 | "name": "validatorAddress", 385 | "type": "string" 386 | }, 387 | { 388 | "internalType": "uint64", 389 | "name": "startingHeight", 390 | "type": "uint64" 391 | }, 392 | { 393 | "internalType": "uint64", 394 | "name": "endingHeight", 395 | "type": "uint64" 396 | }, 397 | { 398 | "components": [ 399 | { 400 | "internalType": "bytes", 401 | "name": "key", 402 | "type": "bytes" 403 | }, 404 | { 405 | "internalType": "uint64", 406 | "name": "offset", 407 | "type": "uint64" 408 | }, 409 | { 410 | "internalType": "uint64", 411 | "name": "limit", 412 | "type": "uint64" 413 | }, 414 | { 415 | "internalType": "bool", 416 | "name": "countTotal", 417 | "type": "bool" 418 | }, 419 | { 420 | "internalType": "bool", 421 | "name": "reverse", 422 | "type": "bool" 423 | } 424 | ], 425 | "internalType": "struct PageRequest", 426 | "name": "pageRequest", 427 | "type": "tuple" 428 | } 429 | ], 430 | "name": "validatorSlashes", 431 | "outputs": [ 432 | { 433 | "components": [ 434 | { 435 | "internalType": "uint64", 436 | "name": "validatorPeriod", 437 | "type": "uint64" 438 | }, 439 | { 440 | "components": [ 441 | { 442 | "internalType": "uint256", 443 | "name": "value", 444 | "type": "uint256" 445 | }, 446 | { 447 | "internalType": "uint8", 448 | "name": "precision", 449 | "type": "uint8" 450 | } 451 | ], 452 | "internalType": "struct Dec", 453 | "name": "fraction", 454 | "type": "tuple" 455 | } 456 | ], 457 | "internalType": "struct ValidatorSlashEvent[]", 458 | "name": "slashes", 459 | "type": "tuple[]" 460 | }, 461 | { 462 | "components": [ 463 | { 464 | "internalType": "bytes", 465 | "name": "nextKey", 466 | "type": "bytes" 467 | }, 468 | { 469 | "internalType": "uint64", 470 | "name": "total", 471 | "type": "uint64" 472 | } 473 | ], 474 | "internalType": "struct PageResponse", 475 | "name": "pageResponse", 476 | "type": "tuple" 477 | } 478 | ], 479 | "stateMutability": "view", 480 | "type": "function" 481 | }, 482 | { 483 | "inputs": [ 484 | { 485 | "internalType": "address", 486 | "name": "delegatorAddress", 487 | "type": "address" 488 | }, 489 | { 490 | "internalType": "string", 491 | "name": "validatorAddress", 492 | "type": "string" 493 | } 494 | ], 495 | "name": "withdrawDelegatorRewards", 496 | "outputs": [ 497 | { 498 | "components": [ 499 | { 500 | "internalType": "string", 501 | "name": "denom", 502 | "type": "string" 503 | }, 504 | { 505 | "internalType": "uint256", 506 | "name": "amount", 507 | "type": "uint256" 508 | } 509 | ], 510 | "internalType": "struct Coin[]", 511 | "name": "amount", 512 | "type": "tuple[]" 513 | } 514 | ], 515 | "stateMutability": "nonpayable", 516 | "type": "function" 517 | }, 518 | { 519 | "inputs": [ 520 | { 521 | "internalType": "string", 522 | "name": "validatorAddress", 523 | "type": "string" 524 | } 525 | ], 526 | "name": "withdrawValidatorCommission", 527 | "outputs": [ 528 | { 529 | "components": [ 530 | { 531 | "internalType": "string", 532 | "name": "denom", 533 | "type": "string" 534 | }, 535 | { 536 | "internalType": "uint256", 537 | "name": "amount", 538 | "type": "uint256" 539 | } 540 | ], 541 | "internalType": "struct Coin[]", 542 | "name": "amount", 543 | "type": "tuple[]" 544 | } 545 | ], 546 | "stateMutability": "nonpayable", 547 | "type": "function" 548 | } 549 | ] 550 | -------------------------------------------------------------------------------- /precompiles/abi/ics20.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "anonymous": false, 4 | "inputs": [ 5 | { 6 | "indexed": true, 7 | "internalType": "address", 8 | "name": "sender", 9 | "type": "address" 10 | }, 11 | { 12 | "indexed": true, 13 | "internalType": "string", 14 | "name": "receiver", 15 | "type": "string" 16 | }, 17 | { 18 | "indexed": false, 19 | "internalType": "string", 20 | "name": "sourcePort", 21 | "type": "string" 22 | }, 23 | { 24 | "indexed": false, 25 | "internalType": "string", 26 | "name": "sourceChannel", 27 | "type": "string" 28 | }, 29 | { 30 | "indexed": false, 31 | "internalType": "string", 32 | "name": "denom", 33 | "type": "string" 34 | }, 35 | { 36 | "indexed": false, 37 | "internalType": "uint256", 38 | "name": "amount", 39 | "type": "uint256" 40 | }, 41 | { 42 | "indexed": false, 43 | "internalType": "string", 44 | "name": "memo", 45 | "type": "string" 46 | } 47 | ], 48 | "name": "IBCTransfer", 49 | "type": "event" 50 | }, 51 | { 52 | "anonymous": false, 53 | "inputs": [ 54 | { 55 | "indexed": true, 56 | "internalType": "address", 57 | "name": "grantee", 58 | "type": "address" 59 | }, 60 | { 61 | "indexed": true, 62 | "internalType": "address", 63 | "name": "granter", 64 | "type": "address" 65 | }, 66 | { 67 | "components": [ 68 | { 69 | "internalType": "string", 70 | "name": "sourcePort", 71 | "type": "string" 72 | }, 73 | { 74 | "internalType": "string", 75 | "name": "sourceChannel", 76 | "type": "string" 77 | }, 78 | { 79 | "components": [ 80 | { 81 | "internalType": "string", 82 | "name": "denom", 83 | "type": "string" 84 | }, 85 | { 86 | "internalType": "uint256", 87 | "name": "amount", 88 | "type": "uint256" 89 | } 90 | ], 91 | "internalType": "struct Coin[]", 92 | "name": "spendLimit", 93 | "type": "tuple[]" 94 | }, 95 | { 96 | "internalType": "string[]", 97 | "name": "allowList", 98 | "type": "string[]" 99 | } 100 | ], 101 | "indexed": false, 102 | "internalType": "struct ICS20Allocation[]", 103 | "name": "allocations", 104 | "type": "tuple[]" 105 | } 106 | ], 107 | "name": "IBCTransferAuthorization", 108 | "type": "event" 109 | }, 110 | { 111 | "inputs": [ 112 | { 113 | "internalType": "address", 114 | "name": "grantee", 115 | "type": "address" 116 | }, 117 | { 118 | "internalType": "address", 119 | "name": "granter", 120 | "type": "address" 121 | } 122 | ], 123 | "name": "allowance", 124 | "outputs": [ 125 | { 126 | "components": [ 127 | { 128 | "internalType": "string", 129 | "name": "sourcePort", 130 | "type": "string" 131 | }, 132 | { 133 | "internalType": "string", 134 | "name": "sourceChannel", 135 | "type": "string" 136 | }, 137 | { 138 | "components": [ 139 | { 140 | "internalType": "string", 141 | "name": "denom", 142 | "type": "string" 143 | }, 144 | { 145 | "internalType": "uint256", 146 | "name": "amount", 147 | "type": "uint256" 148 | } 149 | ], 150 | "internalType": "struct Coin[]", 151 | "name": "spendLimit", 152 | "type": "tuple[]" 153 | }, 154 | { 155 | "internalType": "string[]", 156 | "name": "allowList", 157 | "type": "string[]" 158 | } 159 | ], 160 | "internalType": "struct ICS20Allocation[]", 161 | "name": "allocations", 162 | "type": "tuple[]" 163 | } 164 | ], 165 | "stateMutability": "view", 166 | "type": "function" 167 | }, 168 | { 169 | "inputs": [ 170 | { 171 | "internalType": "address", 172 | "name": "grantee", 173 | "type": "address" 174 | }, 175 | { 176 | "components": [ 177 | { 178 | "internalType": "string", 179 | "name": "sourcePort", 180 | "type": "string" 181 | }, 182 | { 183 | "internalType": "string", 184 | "name": "sourceChannel", 185 | "type": "string" 186 | }, 187 | { 188 | "components": [ 189 | { 190 | "internalType": "string", 191 | "name": "denom", 192 | "type": "string" 193 | }, 194 | { 195 | "internalType": "uint256", 196 | "name": "amount", 197 | "type": "uint256" 198 | } 199 | ], 200 | "internalType": "struct Coin[]", 201 | "name": "spendLimit", 202 | "type": "tuple[]" 203 | }, 204 | { 205 | "internalType": "string[]", 206 | "name": "allowList", 207 | "type": "string[]" 208 | } 209 | ], 210 | "internalType": "struct ICS20Allocation[]", 211 | "name": "allocations", 212 | "type": "tuple[]" 213 | } 214 | ], 215 | "name": "approve", 216 | "outputs": [ 217 | { 218 | "internalType": "bool", 219 | "name": "approved", 220 | "type": "bool" 221 | } 222 | ], 223 | "stateMutability": "nonpayable", 224 | "type": "function" 225 | }, 226 | { 227 | "inputs": [ 228 | { 229 | "internalType": "address", 230 | "name": "grantee", 231 | "type": "address" 232 | }, 233 | { 234 | "internalType": "string", 235 | "name": "sourcePort", 236 | "type": "string" 237 | }, 238 | { 239 | "internalType": "string", 240 | "name": "sourceChannel", 241 | "type": "string" 242 | }, 243 | { 244 | "internalType": "string", 245 | "name": "denom", 246 | "type": "string" 247 | }, 248 | { 249 | "internalType": "uint256", 250 | "name": "amount", 251 | "type": "uint256" 252 | } 253 | ], 254 | "name": "decreaseAllowance", 255 | "outputs": [ 256 | { 257 | "internalType": "bool", 258 | "name": "approved", 259 | "type": "bool" 260 | } 261 | ], 262 | "stateMutability": "nonpayable", 263 | "type": "function" 264 | }, 265 | { 266 | "inputs": [ 267 | { 268 | "internalType": "string", 269 | "name": "trace", 270 | "type": "string" 271 | } 272 | ], 273 | "name": "denomHash", 274 | "outputs": [ 275 | { 276 | "internalType": "string", 277 | "name": "hash", 278 | "type": "string" 279 | } 280 | ], 281 | "stateMutability": "view", 282 | "type": "function" 283 | }, 284 | { 285 | "inputs": [ 286 | { 287 | "internalType": "string", 288 | "name": "hash", 289 | "type": "string" 290 | } 291 | ], 292 | "name": "denomTrace", 293 | "outputs": [ 294 | { 295 | "components": [ 296 | { 297 | "internalType": "string", 298 | "name": "path", 299 | "type": "string" 300 | }, 301 | { 302 | "internalType": "string", 303 | "name": "baseDenom", 304 | "type": "string" 305 | } 306 | ], 307 | "internalType": "struct DenomTrace", 308 | "name": "denomTrace", 309 | "type": "tuple" 310 | } 311 | ], 312 | "stateMutability": "view", 313 | "type": "function" 314 | }, 315 | { 316 | "inputs": [ 317 | { 318 | "components": [ 319 | { 320 | "internalType": "bytes", 321 | "name": "key", 322 | "type": "bytes" 323 | }, 324 | { 325 | "internalType": "uint64", 326 | "name": "offset", 327 | "type": "uint64" 328 | }, 329 | { 330 | "internalType": "uint64", 331 | "name": "limit", 332 | "type": "uint64" 333 | }, 334 | { 335 | "internalType": "bool", 336 | "name": "countTotal", 337 | "type": "bool" 338 | }, 339 | { 340 | "internalType": "bool", 341 | "name": "reverse", 342 | "type": "bool" 343 | } 344 | ], 345 | "internalType": "struct PageRequest", 346 | "name": "pageRequest", 347 | "type": "tuple" 348 | } 349 | ], 350 | "name": "denomTraces", 351 | "outputs": [ 352 | { 353 | "components": [ 354 | { 355 | "internalType": "string", 356 | "name": "path", 357 | "type": "string" 358 | }, 359 | { 360 | "internalType": "string", 361 | "name": "baseDenom", 362 | "type": "string" 363 | } 364 | ], 365 | "internalType": "struct DenomTrace[]", 366 | "name": "denomTraces", 367 | "type": "tuple[]" 368 | }, 369 | { 370 | "components": [ 371 | { 372 | "internalType": "bytes", 373 | "name": "nextKey", 374 | "type": "bytes" 375 | }, 376 | { 377 | "internalType": "uint64", 378 | "name": "total", 379 | "type": "uint64" 380 | } 381 | ], 382 | "internalType": "struct PageResponse", 383 | "name": "pageResponse", 384 | "type": "tuple" 385 | } 386 | ], 387 | "stateMutability": "view", 388 | "type": "function" 389 | }, 390 | { 391 | "inputs": [ 392 | { 393 | "internalType": "address", 394 | "name": "grantee", 395 | "type": "address" 396 | }, 397 | { 398 | "internalType": "string", 399 | "name": "sourcePort", 400 | "type": "string" 401 | }, 402 | { 403 | "internalType": "string", 404 | "name": "sourceChannel", 405 | "type": "string" 406 | }, 407 | { 408 | "internalType": "string", 409 | "name": "denom", 410 | "type": "string" 411 | }, 412 | { 413 | "internalType": "uint256", 414 | "name": "amount", 415 | "type": "uint256" 416 | } 417 | ], 418 | "name": "increaseAllowance", 419 | "outputs": [ 420 | { 421 | "internalType": "bool", 422 | "name": "approved", 423 | "type": "bool" 424 | } 425 | ], 426 | "stateMutability": "nonpayable", 427 | "type": "function" 428 | }, 429 | { 430 | "inputs": [ 431 | { 432 | "internalType": "address", 433 | "name": "grantee", 434 | "type": "address" 435 | } 436 | ], 437 | "name": "revoke", 438 | "outputs": [ 439 | { 440 | "internalType": "bool", 441 | "name": "revoked", 442 | "type": "bool" 443 | } 444 | ], 445 | "stateMutability": "nonpayable", 446 | "type": "function" 447 | }, 448 | { 449 | "inputs": [ 450 | { 451 | "internalType": "string", 452 | "name": "sourcePort", 453 | "type": "string" 454 | }, 455 | { 456 | "internalType": "string", 457 | "name": "sourceChannel", 458 | "type": "string" 459 | }, 460 | { 461 | "internalType": "string", 462 | "name": "denom", 463 | "type": "string" 464 | }, 465 | { 466 | "internalType": "uint256", 467 | "name": "amount", 468 | "type": "uint256" 469 | }, 470 | { 471 | "internalType": "address", 472 | "name": "sender", 473 | "type": "address" 474 | }, 475 | { 476 | "internalType": "string", 477 | "name": "receiver", 478 | "type": "string" 479 | }, 480 | { 481 | "components": [ 482 | { 483 | "internalType": "uint64", 484 | "name": "revisionNumber", 485 | "type": "uint64" 486 | }, 487 | { 488 | "internalType": "uint64", 489 | "name": "revisionHeight", 490 | "type": "uint64" 491 | } 492 | ], 493 | "internalType": "struct Height", 494 | "name": "timeoutHeight", 495 | "type": "tuple" 496 | }, 497 | { 498 | "internalType": "uint64", 499 | "name": "timeoutTimestamp", 500 | "type": "uint64" 501 | }, 502 | { 503 | "internalType": "string", 504 | "name": "memo", 505 | "type": "string" 506 | } 507 | ], 508 | "name": "transfer", 509 | "outputs": [ 510 | { 511 | "internalType": "uint64", 512 | "name": "nextSequence", 513 | "type": "uint64" 514 | } 515 | ], 516 | "stateMutability": "nonpayable", 517 | "type": "function" 518 | } 519 | ] -------------------------------------------------------------------------------- /precompiles/abi/staking.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "anonymous": false, 4 | "inputs": [ 5 | { 6 | "indexed": true, 7 | "internalType": "address", 8 | "name": "grantee", 9 | "type": "address" 10 | }, 11 | { 12 | "indexed": true, 13 | "internalType": "address", 14 | "name": "granter", 15 | "type": "address" 16 | }, 17 | { 18 | "indexed": false, 19 | "internalType": "string[]", 20 | "name": "methods", 21 | "type": "string[]" 22 | }, 23 | { 24 | "indexed": false, 25 | "internalType": "uint256[]", 26 | "name": "values", 27 | "type": "uint256[]" 28 | } 29 | ], 30 | "name": "AllowanceChange", 31 | "type": "event" 32 | }, 33 | { 34 | "anonymous": false, 35 | "inputs": [ 36 | { 37 | "indexed": true, 38 | "internalType": "address", 39 | "name": "grantee", 40 | "type": "address" 41 | }, 42 | { 43 | "indexed": true, 44 | "internalType": "address", 45 | "name": "granter", 46 | "type": "address" 47 | }, 48 | { 49 | "indexed": false, 50 | "internalType": "string[]", 51 | "name": "methods", 52 | "type": "string[]" 53 | }, 54 | { 55 | "indexed": false, 56 | "internalType": "uint256", 57 | "name": "value", 58 | "type": "uint256" 59 | } 60 | ], 61 | "name": "Approval", 62 | "type": "event" 63 | }, 64 | { 65 | "anonymous": false, 66 | "inputs": [ 67 | { 68 | "indexed": true, 69 | "internalType": "address", 70 | "name": "delegatorAddress", 71 | "type": "address" 72 | }, 73 | { 74 | "indexed": true, 75 | "internalType": "string", 76 | "name": "validatorAddress", 77 | "type": "string" 78 | }, 79 | { 80 | "indexed": false, 81 | "internalType": "uint256", 82 | "name": "amount", 83 | "type": "uint256" 84 | }, 85 | { 86 | "indexed": false, 87 | "internalType": "uint256", 88 | "name": "creationHeight", 89 | "type": "uint256" 90 | } 91 | ], 92 | "name": "CancelUnbondingDelegation", 93 | "type": "event" 94 | }, 95 | { 96 | "anonymous": false, 97 | "inputs": [ 98 | { 99 | "indexed": true, 100 | "internalType": "address", 101 | "name": "delegatorAddress", 102 | "type": "address" 103 | }, 104 | { 105 | "indexed": true, 106 | "internalType": "string", 107 | "name": "validatorAddress", 108 | "type": "string" 109 | }, 110 | { 111 | "indexed": false, 112 | "internalType": "uint256", 113 | "name": "amount", 114 | "type": "uint256" 115 | }, 116 | { 117 | "indexed": false, 118 | "internalType": "uint256", 119 | "name": "newShares", 120 | "type": "uint256" 121 | } 122 | ], 123 | "name": "Delegate", 124 | "type": "event" 125 | }, 126 | { 127 | "anonymous": false, 128 | "inputs": [ 129 | { 130 | "indexed": true, 131 | "internalType": "address", 132 | "name": "delegatorAddress", 133 | "type": "address" 134 | }, 135 | { 136 | "indexed": true, 137 | "internalType": "string", 138 | "name": "validatorSrcAddress", 139 | "type": "string" 140 | }, 141 | { 142 | "indexed": true, 143 | "internalType": "string", 144 | "name": "validatorDstAddress", 145 | "type": "string" 146 | }, 147 | { 148 | "indexed": false, 149 | "internalType": "uint256", 150 | "name": "amount", 151 | "type": "uint256" 152 | }, 153 | { 154 | "indexed": false, 155 | "internalType": "uint256", 156 | "name": "completionTime", 157 | "type": "uint256" 158 | } 159 | ], 160 | "name": "Redelegate", 161 | "type": "event" 162 | }, 163 | { 164 | "anonymous": false, 165 | "inputs": [ 166 | { 167 | "indexed": true, 168 | "internalType": "address", 169 | "name": "grantee", 170 | "type": "address" 171 | }, 172 | { 173 | "indexed": true, 174 | "internalType": "address", 175 | "name": "granter", 176 | "type": "address" 177 | }, 178 | { 179 | "indexed": false, 180 | "internalType": "string[]", 181 | "name": "methods", 182 | "type": "string[]" 183 | } 184 | ], 185 | "name": "Revocation", 186 | "type": "event" 187 | }, 188 | { 189 | "anonymous": false, 190 | "inputs": [ 191 | { 192 | "indexed": true, 193 | "internalType": "address", 194 | "name": "delegatorAddress", 195 | "type": "address" 196 | }, 197 | { 198 | "indexed": true, 199 | "internalType": "string", 200 | "name": "validatorAddress", 201 | "type": "string" 202 | }, 203 | { 204 | "indexed": false, 205 | "internalType": "uint256", 206 | "name": "amount", 207 | "type": "uint256" 208 | }, 209 | { 210 | "indexed": false, 211 | "internalType": "uint256", 212 | "name": "completionTime", 213 | "type": "uint256" 214 | } 215 | ], 216 | "name": "Unbond", 217 | "type": "event" 218 | }, 219 | { 220 | "inputs": [ 221 | { 222 | "internalType": "address", 223 | "name": "grantee", 224 | "type": "address" 225 | }, 226 | { 227 | "internalType": "address", 228 | "name": "granter", 229 | "type": "address" 230 | }, 231 | { 232 | "internalType": "string", 233 | "name": "method", 234 | "type": "string" 235 | } 236 | ], 237 | "name": "allowance", 238 | "outputs": [ 239 | { 240 | "internalType": "uint256", 241 | "name": "remaining", 242 | "type": "uint256" 243 | } 244 | ], 245 | "stateMutability": "view", 246 | "type": "function" 247 | }, 248 | { 249 | "inputs": [ 250 | { 251 | "internalType": "address", 252 | "name": "grantee", 253 | "type": "address" 254 | }, 255 | { 256 | "internalType": "uint256", 257 | "name": "amount", 258 | "type": "uint256" 259 | }, 260 | { 261 | "internalType": "string[]", 262 | "name": "methods", 263 | "type": "string[]" 264 | } 265 | ], 266 | "name": "approve", 267 | "outputs": [ 268 | { 269 | "internalType": "bool", 270 | "name": "approved", 271 | "type": "bool" 272 | } 273 | ], 274 | "stateMutability": "nonpayable", 275 | "type": "function" 276 | }, 277 | { 278 | "inputs": [ 279 | { 280 | "internalType": "address", 281 | "name": "delegatorAddress", 282 | "type": "address" 283 | }, 284 | { 285 | "internalType": "string", 286 | "name": "validatorAddress", 287 | "type": "string" 288 | }, 289 | { 290 | "internalType": "uint256", 291 | "name": "amount", 292 | "type": "uint256" 293 | }, 294 | { 295 | "internalType": "uint256", 296 | "name": "creationHeight", 297 | "type": "uint256" 298 | } 299 | ], 300 | "name": "cancelUnbondingDelegation", 301 | "outputs": [ 302 | { 303 | "internalType": "bool", 304 | "name": "success", 305 | "type": "bool" 306 | } 307 | ], 308 | "stateMutability": "nonpayable", 309 | "type": "function" 310 | }, 311 | { 312 | "inputs": [ 313 | { 314 | "internalType": "address", 315 | "name": "grantee", 316 | "type": "address" 317 | }, 318 | { 319 | "internalType": "uint256", 320 | "name": "amount", 321 | "type": "uint256" 322 | }, 323 | { 324 | "internalType": "string[]", 325 | "name": "methods", 326 | "type": "string[]" 327 | } 328 | ], 329 | "name": "decreaseAllowance", 330 | "outputs": [ 331 | { 332 | "internalType": "bool", 333 | "name": "approved", 334 | "type": "bool" 335 | } 336 | ], 337 | "stateMutability": "nonpayable", 338 | "type": "function" 339 | }, 340 | { 341 | "inputs": [ 342 | { 343 | "internalType": "address", 344 | "name": "delegatorAddress", 345 | "type": "address" 346 | }, 347 | { 348 | "internalType": "string", 349 | "name": "validatorAddress", 350 | "type": "string" 351 | }, 352 | { 353 | "internalType": "uint256", 354 | "name": "amount", 355 | "type": "uint256" 356 | } 357 | ], 358 | "name": "delegate", 359 | "outputs": [ 360 | { 361 | "internalType": "bool", 362 | "name": "success", 363 | "type": "bool" 364 | } 365 | ], 366 | "stateMutability": "nonpayable", 367 | "type": "function" 368 | }, 369 | { 370 | "inputs": [ 371 | { 372 | "internalType": "address", 373 | "name": "delegatorAddress", 374 | "type": "address" 375 | }, 376 | { 377 | "internalType": "string", 378 | "name": "validatorAddress", 379 | "type": "string" 380 | } 381 | ], 382 | "name": "delegation", 383 | "outputs": [ 384 | { 385 | "internalType": "uint256", 386 | "name": "shares", 387 | "type": "uint256" 388 | }, 389 | { 390 | "components": [ 391 | { 392 | "internalType": "string", 393 | "name": "denom", 394 | "type": "string" 395 | }, 396 | { 397 | "internalType": "uint256", 398 | "name": "amount", 399 | "type": "uint256" 400 | } 401 | ], 402 | "internalType": "struct Coin", 403 | "name": "balance", 404 | "type": "tuple" 405 | } 406 | ], 407 | "stateMutability": "view", 408 | "type": "function" 409 | }, 410 | { 411 | "inputs": [ 412 | { 413 | "internalType": "address", 414 | "name": "grantee", 415 | "type": "address" 416 | }, 417 | { 418 | "internalType": "uint256", 419 | "name": "amount", 420 | "type": "uint256" 421 | }, 422 | { 423 | "internalType": "string[]", 424 | "name": "methods", 425 | "type": "string[]" 426 | } 427 | ], 428 | "name": "increaseAllowance", 429 | "outputs": [ 430 | { 431 | "internalType": "bool", 432 | "name": "approved", 433 | "type": "bool" 434 | } 435 | ], 436 | "stateMutability": "nonpayable", 437 | "type": "function" 438 | }, 439 | { 440 | "inputs": [ 441 | { 442 | "internalType": "address", 443 | "name": "delegatorAddress", 444 | "type": "address" 445 | }, 446 | { 447 | "internalType": "string", 448 | "name": "validatorSrcAddress", 449 | "type": "string" 450 | }, 451 | { 452 | "internalType": "string", 453 | "name": "validatorDstAddress", 454 | "type": "string" 455 | }, 456 | { 457 | "internalType": "uint256", 458 | "name": "amount", 459 | "type": "uint256" 460 | } 461 | ], 462 | "name": "redelegate", 463 | "outputs": [ 464 | { 465 | "internalType": "int64", 466 | "name": "completionTime", 467 | "type": "int64" 468 | } 469 | ], 470 | "stateMutability": "nonpayable", 471 | "type": "function" 472 | }, 473 | { 474 | "inputs": [ 475 | { 476 | "internalType": "address", 477 | "name": "delegatorAddress", 478 | "type": "address" 479 | }, 480 | { 481 | "internalType": "string", 482 | "name": "srcValidatorAddress", 483 | "type": "string" 484 | }, 485 | { 486 | "internalType": "string", 487 | "name": "dstValidatorAddress", 488 | "type": "string" 489 | } 490 | ], 491 | "name": "redelegation", 492 | "outputs": [ 493 | { 494 | "components": [ 495 | { 496 | "internalType": "int64", 497 | "name": "creationHeight", 498 | "type": "int64" 499 | }, 500 | { 501 | "internalType": "int64", 502 | "name": "completionTime", 503 | "type": "int64" 504 | }, 505 | { 506 | "internalType": "uint256", 507 | "name": "initialBalance", 508 | "type": "uint256" 509 | }, 510 | { 511 | "internalType": "uint256", 512 | "name": "sharesDst", 513 | "type": "uint256" 514 | } 515 | ], 516 | "internalType": "struct RedelegationEntry[]", 517 | "name": "entries", 518 | "type": "tuple[]" 519 | } 520 | ], 521 | "stateMutability": "view", 522 | "type": "function" 523 | }, 524 | { 525 | "inputs": [ 526 | { 527 | "internalType": "address", 528 | "name": "delegatorAddress", 529 | "type": "address" 530 | }, 531 | { 532 | "internalType": "string", 533 | "name": "srcValidatorAddress", 534 | "type": "string" 535 | }, 536 | { 537 | "internalType": "string", 538 | "name": "dstValidatorAddress", 539 | "type": "string" 540 | }, 541 | { 542 | "components": [ 543 | { 544 | "internalType": "bytes", 545 | "name": "key", 546 | "type": "bytes" 547 | }, 548 | { 549 | "internalType": "uint64", 550 | "name": "offset", 551 | "type": "uint64" 552 | }, 553 | { 554 | "internalType": "uint64", 555 | "name": "limit", 556 | "type": "uint64" 557 | }, 558 | { 559 | "internalType": "bool", 560 | "name": "countTotal", 561 | "type": "bool" 562 | }, 563 | { 564 | "internalType": "bool", 565 | "name": "reverse", 566 | "type": "bool" 567 | } 568 | ], 569 | "internalType": "struct PageRequest", 570 | "name": "pageRequest", 571 | "type": "tuple" 572 | } 573 | ], 574 | "name": "redelegations", 575 | "outputs": [ 576 | { 577 | "components": [ 578 | { 579 | "components": [ 580 | { 581 | "internalType": "string", 582 | "name": "delegatorAddress", 583 | "type": "string" 584 | }, 585 | { 586 | "internalType": "string", 587 | "name": "validatorSrcAddress", 588 | "type": "string" 589 | }, 590 | { 591 | "internalType": "string", 592 | "name": "validatorDstAddress", 593 | "type": "string" 594 | }, 595 | { 596 | "components": [ 597 | { 598 | "internalType": "int64", 599 | "name": "creationHeight", 600 | "type": "int64" 601 | }, 602 | { 603 | "internalType": "int64", 604 | "name": "completionTime", 605 | "type": "int64" 606 | }, 607 | { 608 | "internalType": "uint256", 609 | "name": "initialBalance", 610 | "type": "uint256" 611 | }, 612 | { 613 | "internalType": "uint256", 614 | "name": "sharesDst", 615 | "type": "uint256" 616 | } 617 | ], 618 | "internalType": "struct RedelegationEntry[]", 619 | "name": "entries", 620 | "type": "tuple[]" 621 | } 622 | ], 623 | "internalType": "struct Redelegation", 624 | "name": "redelegation", 625 | "type": "tuple" 626 | }, 627 | { 628 | "components": [ 629 | { 630 | "components": [ 631 | { 632 | "internalType": "int64", 633 | "name": "creationHeight", 634 | "type": "int64" 635 | }, 636 | { 637 | "internalType": "int64", 638 | "name": "completionTime", 639 | "type": "int64" 640 | }, 641 | { 642 | "internalType": "uint256", 643 | "name": "initialBalance", 644 | "type": "uint256" 645 | }, 646 | { 647 | "internalType": "uint256", 648 | "name": "sharesDst", 649 | "type": "uint256" 650 | } 651 | ], 652 | "internalType": "struct RedelegationEntry", 653 | "name": "redelegationEntry", 654 | "type": "tuple" 655 | }, 656 | { 657 | "internalType": "uint256", 658 | "name": "balance", 659 | "type": "uint256" 660 | } 661 | ], 662 | "internalType": "struct RedelegationEntryResponse[]", 663 | "name": "entries", 664 | "type": "tuple[]" 665 | } 666 | ], 667 | "internalType": "struct RedelegationResponse[]", 668 | "name": "response", 669 | "type": "tuple[]" 670 | }, 671 | { 672 | "components": [ 673 | { 674 | "internalType": "bytes", 675 | "name": "nextKey", 676 | "type": "bytes" 677 | }, 678 | { 679 | "internalType": "uint64", 680 | "name": "total", 681 | "type": "uint64" 682 | } 683 | ], 684 | "internalType": "struct PageResponse", 685 | "name": "pageResponse", 686 | "type": "tuple" 687 | } 688 | ], 689 | "stateMutability": "view", 690 | "type": "function" 691 | }, 692 | { 693 | "inputs": [ 694 | { 695 | "internalType": "address", 696 | "name": "grantee", 697 | "type": "address" 698 | }, 699 | { 700 | "internalType": "string[]", 701 | "name": "methods", 702 | "type": "string[]" 703 | } 704 | ], 705 | "name": "revoke", 706 | "outputs": [ 707 | { 708 | "internalType": "bool", 709 | "name": "revoked", 710 | "type": "bool" 711 | } 712 | ], 713 | "stateMutability": "nonpayable", 714 | "type": "function" 715 | }, 716 | { 717 | "inputs": [ 718 | { 719 | "internalType": "address", 720 | "name": "delegatorAddress", 721 | "type": "address" 722 | }, 723 | { 724 | "internalType": "string", 725 | "name": "validatorAddress", 726 | "type": "string" 727 | } 728 | ], 729 | "name": "unbondingDelegation", 730 | "outputs": [ 731 | { 732 | "components": [ 733 | { 734 | "internalType": "int64", 735 | "name": "creationHeight", 736 | "type": "int64" 737 | }, 738 | { 739 | "internalType": "int64", 740 | "name": "completionTime", 741 | "type": "int64" 742 | }, 743 | { 744 | "internalType": "uint256", 745 | "name": "initialBalance", 746 | "type": "uint256" 747 | }, 748 | { 749 | "internalType": "uint256", 750 | "name": "balance", 751 | "type": "uint256" 752 | } 753 | ], 754 | "internalType": "struct UnbondingDelegationEntry[]", 755 | "name": "entries", 756 | "type": "tuple[]" 757 | } 758 | ], 759 | "stateMutability": "view", 760 | "type": "function" 761 | }, 762 | { 763 | "inputs": [ 764 | { 765 | "internalType": "address", 766 | "name": "delegatorAddress", 767 | "type": "address" 768 | }, 769 | { 770 | "internalType": "string", 771 | "name": "validatorAddress", 772 | "type": "string" 773 | }, 774 | { 775 | "internalType": "uint256", 776 | "name": "amount", 777 | "type": "uint256" 778 | } 779 | ], 780 | "name": "undelegate", 781 | "outputs": [ 782 | { 783 | "internalType": "int64", 784 | "name": "completionTime", 785 | "type": "int64" 786 | } 787 | ], 788 | "stateMutability": "nonpayable", 789 | "type": "function" 790 | }, 791 | { 792 | "inputs": [ 793 | { 794 | "internalType": "string", 795 | "name": "validatorAddress", 796 | "type": "string" 797 | } 798 | ], 799 | "name": "validator", 800 | "outputs": [ 801 | { 802 | "components": [ 803 | { 804 | "internalType": "string", 805 | "name": "operatorAddress", 806 | "type": "string" 807 | }, 808 | { 809 | "internalType": "string", 810 | "name": "consensusPubkey", 811 | "type": "string" 812 | }, 813 | { 814 | "internalType": "bool", 815 | "name": "jailed", 816 | "type": "bool" 817 | }, 818 | { 819 | "internalType": "enum BondStatus", 820 | "name": "status", 821 | "type": "uint8" 822 | }, 823 | { 824 | "internalType": "uint256", 825 | "name": "tokens", 826 | "type": "uint256" 827 | }, 828 | { 829 | "internalType": "uint256", 830 | "name": "delegatorShares", 831 | "type": "uint256" 832 | }, 833 | { 834 | "internalType": "string", 835 | "name": "description", 836 | "type": "string" 837 | }, 838 | { 839 | "internalType": "int64", 840 | "name": "unbondingHeight", 841 | "type": "int64" 842 | }, 843 | { 844 | "internalType": "int64", 845 | "name": "unbondingTime", 846 | "type": "int64" 847 | }, 848 | { 849 | "internalType": "uint256", 850 | "name": "commission", 851 | "type": "uint256" 852 | }, 853 | { 854 | "internalType": "uint256", 855 | "name": "minSelfDelegation", 856 | "type": "uint256" 857 | } 858 | ], 859 | "internalType": "struct Validator", 860 | "name": "validator", 861 | "type": "tuple" 862 | } 863 | ], 864 | "stateMutability": "view", 865 | "type": "function" 866 | }, 867 | { 868 | "inputs": [ 869 | { 870 | "internalType": "string", 871 | "name": "status", 872 | "type": "string" 873 | }, 874 | { 875 | "components": [ 876 | { 877 | "internalType": "bytes", 878 | "name": "key", 879 | "type": "bytes" 880 | }, 881 | { 882 | "internalType": "uint64", 883 | "name": "offset", 884 | "type": "uint64" 885 | }, 886 | { 887 | "internalType": "uint64", 888 | "name": "limit", 889 | "type": "uint64" 890 | }, 891 | { 892 | "internalType": "bool", 893 | "name": "countTotal", 894 | "type": "bool" 895 | }, 896 | { 897 | "internalType": "bool", 898 | "name": "reverse", 899 | "type": "bool" 900 | } 901 | ], 902 | "internalType": "struct PageRequest", 903 | "name": "pageRequest", 904 | "type": "tuple" 905 | } 906 | ], 907 | "name": "validators", 908 | "outputs": [ 909 | { 910 | "components": [ 911 | { 912 | "internalType": "string", 913 | "name": "operatorAddress", 914 | "type": "string" 915 | }, 916 | { 917 | "internalType": "string", 918 | "name": "consensusPubkey", 919 | "type": "string" 920 | }, 921 | { 922 | "internalType": "bool", 923 | "name": "jailed", 924 | "type": "bool" 925 | }, 926 | { 927 | "internalType": "enum BondStatus", 928 | "name": "status", 929 | "type": "uint8" 930 | }, 931 | { 932 | "internalType": "uint256", 933 | "name": "tokens", 934 | "type": "uint256" 935 | }, 936 | { 937 | "internalType": "uint256", 938 | "name": "delegatorShares", 939 | "type": "uint256" 940 | }, 941 | { 942 | "internalType": "string", 943 | "name": "description", 944 | "type": "string" 945 | }, 946 | { 947 | "internalType": "int64", 948 | "name": "unbondingHeight", 949 | "type": "int64" 950 | }, 951 | { 952 | "internalType": "int64", 953 | "name": "unbondingTime", 954 | "type": "int64" 955 | }, 956 | { 957 | "internalType": "uint256", 958 | "name": "commission", 959 | "type": "uint256" 960 | }, 961 | { 962 | "internalType": "uint256", 963 | "name": "minSelfDelegation", 964 | "type": "uint256" 965 | } 966 | ], 967 | "internalType": "struct Validator[]", 968 | "name": "validators", 969 | "type": "tuple[]" 970 | }, 971 | { 972 | "components": [ 973 | { 974 | "internalType": "bytes", 975 | "name": "nextKey", 976 | "type": "bytes" 977 | }, 978 | { 979 | "internalType": "uint64", 980 | "name": "total", 981 | "type": "uint64" 982 | } 983 | ], 984 | "internalType": "struct PageResponse", 985 | "name": "pageResponse", 986 | "type": "tuple" 987 | } 988 | ], 989 | "stateMutability": "view", 990 | "type": "function" 991 | } 992 | ] -------------------------------------------------------------------------------- /precompiles/abi/vesting.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "anonymous": false, 4 | "inputs": [ 5 | { 6 | "indexed": true, 7 | "internalType": "address", 8 | "name": "grantee", 9 | "type": "address" 10 | }, 11 | { 12 | "indexed": true, 13 | "internalType": "address", 14 | "name": "granter", 15 | "type": "address" 16 | }, 17 | { 18 | "indexed": false, 19 | "internalType": "string", 20 | "name": "method", 21 | "type": "string" 22 | } 23 | ], 24 | "name": "Approval", 25 | "type": "event" 26 | }, 27 | { 28 | "anonymous": false, 29 | "inputs": [ 30 | { 31 | "indexed": true, 32 | "internalType": "address", 33 | "name": "funderAddress", 34 | "type": "address" 35 | }, 36 | { 37 | "indexed": true, 38 | "internalType": "address", 39 | "name": "accountAddress", 40 | "type": "address" 41 | }, 42 | { 43 | "indexed": false, 44 | "internalType": "address", 45 | "name": "destAddress", 46 | "type": "address" 47 | } 48 | ], 49 | "name": "Clawback", 50 | "type": "event" 51 | }, 52 | { 53 | "anonymous": false, 54 | "inputs": [ 55 | { 56 | "indexed": true, 57 | "internalType": "address", 58 | "name": "vestingAddress", 59 | "type": "address" 60 | } 61 | ], 62 | "name": "ConvertVestingAccount", 63 | "type": "event" 64 | }, 65 | { 66 | "anonymous": false, 67 | "inputs": [ 68 | { 69 | "indexed": true, 70 | "internalType": "address", 71 | "name": "funderAddress", 72 | "type": "address" 73 | }, 74 | { 75 | "indexed": true, 76 | "internalType": "address", 77 | "name": "vestingAddress", 78 | "type": "address" 79 | } 80 | ], 81 | "name": "CreateClawbackVestingAccount", 82 | "type": "event" 83 | }, 84 | { 85 | "anonymous": false, 86 | "inputs": [ 87 | { 88 | "indexed": true, 89 | "internalType": "address", 90 | "name": "funderAddress", 91 | "type": "address" 92 | }, 93 | { 94 | "indexed": true, 95 | "internalType": "address", 96 | "name": "vestingAddress", 97 | "type": "address" 98 | }, 99 | { 100 | "indexed": false, 101 | "internalType": "uint64", 102 | "name": "startTime", 103 | "type": "uint64" 104 | }, 105 | { 106 | "components": [ 107 | { 108 | "internalType": "int64", 109 | "name": "length", 110 | "type": "int64" 111 | }, 112 | { 113 | "components": [ 114 | { 115 | "internalType": "string", 116 | "name": "denom", 117 | "type": "string" 118 | }, 119 | { 120 | "internalType": "uint256", 121 | "name": "amount", 122 | "type": "uint256" 123 | } 124 | ], 125 | "internalType": "struct Coin[]", 126 | "name": "amount", 127 | "type": "tuple[]" 128 | } 129 | ], 130 | "indexed": false, 131 | "internalType": "struct Period[]", 132 | "name": "lockupPeriods", 133 | "type": "tuple[]" 134 | }, 135 | { 136 | "components": [ 137 | { 138 | "internalType": "int64", 139 | "name": "length", 140 | "type": "int64" 141 | }, 142 | { 143 | "components": [ 144 | { 145 | "internalType": "string", 146 | "name": "denom", 147 | "type": "string" 148 | }, 149 | { 150 | "internalType": "uint256", 151 | "name": "amount", 152 | "type": "uint256" 153 | } 154 | ], 155 | "internalType": "struct Coin[]", 156 | "name": "amount", 157 | "type": "tuple[]" 158 | } 159 | ], 160 | "indexed": false, 161 | "internalType": "struct Period[]", 162 | "name": "vestingPeriods", 163 | "type": "tuple[]" 164 | } 165 | ], 166 | "name": "FundVestingAccount", 167 | "type": "event" 168 | }, 169 | { 170 | "anonymous": false, 171 | "inputs": [ 172 | { 173 | "indexed": true, 174 | "internalType": "address", 175 | "name": "funderAddress", 176 | "type": "address" 177 | }, 178 | { 179 | "indexed": true, 180 | "internalType": "address", 181 | "name": "vestingAddress", 182 | "type": "address" 183 | }, 184 | { 185 | "indexed": false, 186 | "internalType": "address", 187 | "name": "newFunderAddress", 188 | "type": "address" 189 | } 190 | ], 191 | "name": "UpdateVestingFunder", 192 | "type": "event" 193 | }, 194 | { 195 | "inputs": [ 196 | { 197 | "internalType": "address", 198 | "name": "grantee", 199 | "type": "address" 200 | }, 201 | { 202 | "internalType": "string", 203 | "name": "method", 204 | "type": "string" 205 | } 206 | ], 207 | "name": "approve", 208 | "outputs": [ 209 | { 210 | "internalType": "bool", 211 | "name": "approved", 212 | "type": "bool" 213 | } 214 | ], 215 | "stateMutability": "nonpayable", 216 | "type": "function" 217 | }, 218 | { 219 | "inputs": [ 220 | { 221 | "internalType": "address", 222 | "name": "vestingAddress", 223 | "type": "address" 224 | } 225 | ], 226 | "name": "balances", 227 | "outputs": [ 228 | { 229 | "components": [ 230 | { 231 | "internalType": "string", 232 | "name": "denom", 233 | "type": "string" 234 | }, 235 | { 236 | "internalType": "uint256", 237 | "name": "amount", 238 | "type": "uint256" 239 | } 240 | ], 241 | "internalType": "struct Coin[]", 242 | "name": "locked", 243 | "type": "tuple[]" 244 | }, 245 | { 246 | "components": [ 247 | { 248 | "internalType": "string", 249 | "name": "denom", 250 | "type": "string" 251 | }, 252 | { 253 | "internalType": "uint256", 254 | "name": "amount", 255 | "type": "uint256" 256 | } 257 | ], 258 | "internalType": "struct Coin[]", 259 | "name": "unvested", 260 | "type": "tuple[]" 261 | }, 262 | { 263 | "components": [ 264 | { 265 | "internalType": "string", 266 | "name": "denom", 267 | "type": "string" 268 | }, 269 | { 270 | "internalType": "uint256", 271 | "name": "amount", 272 | "type": "uint256" 273 | } 274 | ], 275 | "internalType": "struct Coin[]", 276 | "name": "vested", 277 | "type": "tuple[]" 278 | } 279 | ], 280 | "stateMutability": "view", 281 | "type": "function" 282 | }, 283 | { 284 | "inputs": [ 285 | { 286 | "internalType": "address", 287 | "name": "funderAddress", 288 | "type": "address" 289 | }, 290 | { 291 | "internalType": "address", 292 | "name": "accountAddress", 293 | "type": "address" 294 | }, 295 | { 296 | "internalType": "address", 297 | "name": "destAddress", 298 | "type": "address" 299 | } 300 | ], 301 | "name": "clawback", 302 | "outputs": [ 303 | { 304 | "components": [ 305 | { 306 | "internalType": "string", 307 | "name": "denom", 308 | "type": "string" 309 | }, 310 | { 311 | "internalType": "uint256", 312 | "name": "amount", 313 | "type": "uint256" 314 | } 315 | ], 316 | "internalType": "struct Coin[]", 317 | "name": "", 318 | "type": "tuple[]" 319 | } 320 | ], 321 | "stateMutability": "nonpayable", 322 | "type": "function" 323 | }, 324 | { 325 | "inputs": [ 326 | { 327 | "internalType": "address", 328 | "name": "vestingAddress", 329 | "type": "address" 330 | } 331 | ], 332 | "name": "convertVestingAccount", 333 | "outputs": [ 334 | { 335 | "internalType": "bool", 336 | "name": "success", 337 | "type": "bool" 338 | } 339 | ], 340 | "stateMutability": "nonpayable", 341 | "type": "function" 342 | }, 343 | { 344 | "inputs": [ 345 | { 346 | "internalType": "address", 347 | "name": "funderAddress", 348 | "type": "address" 349 | }, 350 | { 351 | "internalType": "address", 352 | "name": "vestingAddress", 353 | "type": "address" 354 | }, 355 | { 356 | "internalType": "bool", 357 | "name": "enableGovClawback", 358 | "type": "bool" 359 | } 360 | ], 361 | "name": "createClawbackVestingAccount", 362 | "outputs": [ 363 | { 364 | "internalType": "bool", 365 | "name": "success", 366 | "type": "bool" 367 | } 368 | ], 369 | "stateMutability": "nonpayable", 370 | "type": "function" 371 | }, 372 | { 373 | "inputs": [ 374 | { 375 | "internalType": "address", 376 | "name": "funderAddress", 377 | "type": "address" 378 | }, 379 | { 380 | "internalType": "address", 381 | "name": "vestingAddress", 382 | "type": "address" 383 | }, 384 | { 385 | "internalType": "uint64", 386 | "name": "startTime", 387 | "type": "uint64" 388 | }, 389 | { 390 | "components": [ 391 | { 392 | "internalType": "int64", 393 | "name": "length", 394 | "type": "int64" 395 | }, 396 | { 397 | "components": [ 398 | { 399 | "internalType": "string", 400 | "name": "denom", 401 | "type": "string" 402 | }, 403 | { 404 | "internalType": "uint256", 405 | "name": "amount", 406 | "type": "uint256" 407 | } 408 | ], 409 | "internalType": "struct Coin[]", 410 | "name": "amount", 411 | "type": "tuple[]" 412 | } 413 | ], 414 | "internalType": "struct Period[]", 415 | "name": "lockupPeriods", 416 | "type": "tuple[]" 417 | }, 418 | { 419 | "components": [ 420 | { 421 | "internalType": "int64", 422 | "name": "length", 423 | "type": "int64" 424 | }, 425 | { 426 | "components": [ 427 | { 428 | "internalType": "string", 429 | "name": "denom", 430 | "type": "string" 431 | }, 432 | { 433 | "internalType": "uint256", 434 | "name": "amount", 435 | "type": "uint256" 436 | } 437 | ], 438 | "internalType": "struct Coin[]", 439 | "name": "amount", 440 | "type": "tuple[]" 441 | } 442 | ], 443 | "internalType": "struct Period[]", 444 | "name": "vestingPeriods", 445 | "type": "tuple[]" 446 | } 447 | ], 448 | "name": "fundVestingAccount", 449 | "outputs": [ 450 | { 451 | "internalType": "bool", 452 | "name": "success", 453 | "type": "bool" 454 | } 455 | ], 456 | "stateMutability": "nonpayable", 457 | "type": "function" 458 | }, 459 | { 460 | "inputs": [ 461 | { 462 | "internalType": "address", 463 | "name": "funderAddress", 464 | "type": "address" 465 | }, 466 | { 467 | "internalType": "address", 468 | "name": "newFunderAddress", 469 | "type": "address" 470 | }, 471 | { 472 | "internalType": "address", 473 | "name": "vestingAddress", 474 | "type": "address" 475 | } 476 | ], 477 | "name": "updateVestingFunder", 478 | "outputs": [ 479 | { 480 | "internalType": "bool", 481 | "name": "success", 482 | "type": "bool" 483 | } 484 | ], 485 | "stateMutability": "nonpayable", 486 | "type": "function" 487 | } 488 | ] -------------------------------------------------------------------------------- /precompiles/common/Authorization.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: LGPL-3.0-only 2 | pragma solidity >=0.8.17 .0; 3 | 4 | /// @author Evmos Team 5 | /// @title Authorization Interface 6 | /// @dev The interface through which solidity contracts will interact with smart contract approvals. 7 | interface AuthorizationI { 8 | /// @dev Approves a list of Cosmos or IBC transactions with a specific amount of tokens. 9 | /// @param spender The address which will spend the funds. 10 | /// @param amount The amount of tokens to be spent. 11 | /// @param methods The message type URLs of the methods to approve. 12 | /// @return approved Boolean value to indicate if the approval was successful. 13 | function approve( 14 | address spender, 15 | uint256 amount, 16 | string[] calldata methods 17 | ) external returns (bool approved); 18 | 19 | /// @dev Revokes a list of Cosmos transactions. 20 | /// @param spender The address which will spend the funds. 21 | /// @param methods The message type URLs of the methods to revoke. 22 | /// @return revoked Boolean value to indicate if the revocation was successful. 23 | function revoke( 24 | address spender, 25 | string[] calldata methods 26 | ) external returns (bool revoked); 27 | 28 | /// @dev Increase the allowance of a given spender by a specific amount of tokens for IBC 29 | /// transfer methods or staking. 30 | /// @param spender The address which will spend the funds. 31 | /// @param amount The amount of tokens to be spent. 32 | /// @param methods The message type URLs of the methods to approve. 33 | /// @return approved Boolean value to indicate if the approval was successful. 34 | function increaseAllowance( 35 | address spender, 36 | uint256 amount, 37 | string[] calldata methods 38 | ) external returns (bool approved); 39 | 40 | /// @dev Decreases the allowance of a given spender by a specific amount of tokens for IBC 41 | /// transfer methods or staking. 42 | /// @param spender The address which will spend the funds. 43 | /// @param amount The amount of tokens to be spent. 44 | /// @param methods The message type URLs of the methods to approve. 45 | /// @return approved Boolean value to indicate if the approval was successful. 46 | function decreaseAllowance( 47 | address spender, 48 | uint256 amount, 49 | string[] calldata methods 50 | ) external returns (bool approved); 51 | 52 | /// @dev Returns the remaining number of tokens that spender will be allowed to spend 53 | /// on behalf of the owner through IBC transfer methods or staking. This is zero by default. 54 | /// @param owner The address of the account owning tokens. 55 | /// @param spender The address of the account able to transfer the tokens. 56 | /// @param method The message type URL of the methods for which the approval should be queried. 57 | /// @return remaining The remaining number of tokens available to be spent. 58 | function allowance( 59 | address owner, 60 | address spender, 61 | string calldata method 62 | ) external view returns (uint256 remaining); 63 | 64 | /// @dev This event is emitted when the allowance of a spender is set by a call to the approve method. 65 | /// The value field specifies the new allowance and the methods field holds the information for which methods 66 | /// the approval was set. 67 | /// @param owner The owner of the tokens. 68 | /// @param spender The address which will spend the funds. 69 | /// @param methods The message type URLs of the methods for which the approval is set. 70 | /// @param value The amount of tokens approved to be spent. 71 | event Approval( 72 | address indexed owner, 73 | address indexed spender, 74 | string[] methods, 75 | uint256 value 76 | ); 77 | 78 | /// @dev This event is emitted when an owner revokes a spender's allowance. 79 | /// @param owner The owner of the tokens. 80 | /// @param spender The address which will spend the funds. 81 | /// @param methods The message type URLs of the methods for which the approval is set. 82 | event Revocation( 83 | address indexed owner, 84 | address indexed spender, 85 | string[] methods 86 | ); 87 | 88 | /// @dev This event is emitted when the allowance of a spender is changed by a call to the decrease or increase 89 | /// allowance method. The values field specifies the new allowances and the methods field holds the 90 | /// information for which methods the approval was set. 91 | /// @param owner The owner of the tokens. 92 | /// @param spender The address which will spend the funds. 93 | /// @param methods The message type URLs of the methods for which the approval is set. 94 | /// @param values The amounts of tokens approved to be spent. 95 | event AllowanceChange( 96 | address indexed owner, 97 | address indexed spender, 98 | string[] methods, 99 | uint256[] values 100 | ); 101 | } 102 | -------------------------------------------------------------------------------- /precompiles/common/IICS20Authorization.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: LGPL-3.0-only 2 | pragma solidity >=0.8.17; 3 | 4 | import "Types.sol"; 5 | 6 | /// @author Evmos Team 7 | /// @title Authorization Interface 8 | /// @dev The interface through which solidity contracts will interact with smart contract approvals. 9 | interface IICS20Authorization { 10 | /// @dev Emitted when an ICS-20 transfer authorization is granted. 11 | /// @param grantee The address of the grantee. 12 | /// @param granter The address of the granter. 13 | /// @param allocations An array of Allocation authorized with this grant. 14 | event IBCTransferAuthorization( 15 | address indexed grantee, 16 | address indexed granter, 17 | ICS20Allocation[] allocations 18 | ); 19 | 20 | /// @dev Approves IBC transfer with a specific amount of tokens. 21 | /// @param grantee The address for which the transfer authorization is granted. 22 | /// @param allocations An array of ICS20Allocation for the authorization. 23 | function approve(address grantee, ICS20Allocation[] calldata allocations) external returns (bool approved); 24 | 25 | /// @dev Revokes IBC transfer authorization for a specific grantee. 26 | /// @param grantee The address for which the transfer authorization will be revoked. 27 | function revoke(address grantee) external returns (bool revoked); 28 | 29 | /// @dev Increase the allowance of a given grantee by a specific amount of tokens for IBC transfer methods. 30 | /// @param grantee The address of the contract that is allowed to spend the granter's tokens. 31 | /// @param sourcePort The port on which the packet will be sent. 32 | /// @param sourceChannel The channel by which the packet will be sent. 33 | /// @param denom The denomination of the Coin to be transferred to the receiver. 34 | /// @param amount The increase in amount of tokens that can be spent. 35 | /// @return approved Is true if the operation ran successfully. 36 | function increaseAllowance( 37 | address grantee, 38 | string calldata sourcePort, 39 | string calldata sourceChannel, 40 | string calldata denom, 41 | uint256 amount 42 | ) external returns (bool approved); 43 | 44 | /// @dev Decreases the allowance of a given grantee by a specific amount of tokens for IBC transfer methods. 45 | /// @param grantee The address of the contract that is allowed to spend the granter's tokens. 46 | /// @param sourcePort The port on which the packet will be sent. 47 | /// @param sourceChannel The channel by which the packet will be sent. 48 | /// @param denom The denomination of the Coin to be transferred to the receiver. 49 | /// @param amount The amount by which the spendable tokens are decreased. 50 | /// @return approved Is true if the operation ran successfully. 51 | function decreaseAllowance( 52 | address grantee, 53 | string calldata sourcePort, 54 | string calldata sourceChannel, 55 | string calldata denom, 56 | uint256 amount 57 | ) external returns (bool approved); 58 | 59 | /// @dev Returns the remaining number of tokens that a grantee 60 | /// will be allowed to spend on behalf of granter through 61 | /// IBC transfers. This is an empty array by default. 62 | /// @param grantee The address of the contract that is allowed to spend the granter's tokens. 63 | /// @param granter The address of the account able to transfer the tokens. 64 | /// @return allocations The remaining amounts allowed to be spent for 65 | /// corresponding source port and channel. 66 | function allowance( 67 | address grantee, 68 | address granter 69 | ) external view returns (ICS20Allocation[] memory allocations); 70 | } -------------------------------------------------------------------------------- /precompiles/common/Types.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: LGPL-3.0-only 2 | pragma solidity >=0.8.17; 3 | 4 | 5 | /// @dev ICS20Allocation represents a single allocation for an IBC fungible token transfer. 6 | struct ICS20Allocation { 7 | string sourcePort; 8 | string sourceChannel; 9 | Coin[] spendLimit; 10 | string[] allowList; 11 | } 12 | 13 | /// @dev Dec represents a fixed point decimal value. The value is stored as an integer, and the 14 | /// precision is stored as a uint8. The value is multiplied by 10^precision to get the actual value. 15 | struct Dec { 16 | uint256 value; 17 | uint8 precision; 18 | } 19 | 20 | /// @dev Coin is a struct that represents a token with a denomination and an amount. 21 | struct Coin { 22 | string denom; 23 | uint256 amount; 24 | } 25 | 26 | /// @dev DecCoin is a struct that represents a token with a denomination, an amount and a precision. 27 | struct DecCoin { 28 | string denom; 29 | uint256 amount; 30 | uint8 precision; 31 | } 32 | 33 | /// @dev PageResponse is a struct that represents a page response. 34 | struct PageResponse { 35 | bytes nextKey; 36 | uint64 total; 37 | } 38 | 39 | /// @dev PageRequest is a struct that represents a page request. 40 | struct PageRequest { 41 | bytes key; 42 | uint64 offset; 43 | uint64 limit; 44 | bool countTotal; 45 | bool reverse; 46 | } 47 | 48 | /// @dev Height is a monotonically increasing data type 49 | /// that can be compared against another Height for the purposes of updating and 50 | /// freezing clients 51 | /// 52 | /// Normally the RevisionHeight is incremented at each height while keeping 53 | /// RevisionNumber the same. However some consensus algorithms may choose to 54 | /// reset the height in certain conditions e.g. hard forks, state-machine 55 | /// breaking changes In these cases, the RevisionNumber is incremented so that 56 | /// height continues to be monotonically increasing even as the RevisionHeight 57 | /// gets reset 58 | struct Height { 59 | // the revision that the client is currently on 60 | uint64 revisionNumber; 61 | // the height within the given revision 62 | uint64 revisionHeight; 63 | } 64 | -------------------------------------------------------------------------------- /precompiles/stateful/Distribution.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: LGPL-3.0-only 2 | pragma solidity >=0.8.18; 3 | 4 | import "../common/Types.sol"; 5 | 6 | /// @dev The DistributionI contract's address. 7 | address constant DISTRIBUTION_PRECOMPILE_ADDRESS = 0x0000000000000000000000000000000000000801; 8 | 9 | /// @dev Define all the available distribution methods. 10 | string constant MSG_SET_WITHDRAWER_ADDRESS = "/cosmos.distribution.v1beta1.MsgSetWithdrawAddress"; 11 | string constant MSG_WITHDRAW_DELEGATOR_REWARD = "/cosmos.distribution.v1beta1.MsgWithdrawDelegatorReward"; 12 | string constant MSG_WITHDRAW_VALIDATOR_COMMISSION = "/cosmos.distribution.v1beta1.MsgWithdrawValidatorCommission"; 13 | 14 | /// @dev The DistributionI contract's instance. 15 | DistributionI constant DISTRIBUTION_CONTRACT = DistributionI( 16 | DISTRIBUTION_PRECOMPILE_ADDRESS 17 | ); 18 | 19 | struct ValidatorSlashEvent { 20 | uint64 validatorPeriod; 21 | Dec fraction; 22 | } 23 | 24 | struct ValidatorDistributionInfo { 25 | string operatorAddress; 26 | DecCoin[] selfBondRewards; 27 | DecCoin[] commission; 28 | } 29 | 30 | struct DelegationDelegatorReward { 31 | string validatorAddress; 32 | DecCoin[] reward; 33 | } 34 | 35 | /// @author Evmos Team 36 | /// @title Distribution Precompile Contract 37 | /// @dev The interface through which solidity contracts will interact with Distribution 38 | /// @custom:address 0x0000000000000000000000000000000000000801 39 | interface DistributionI { 40 | /// TRANSACTIONS 41 | /// @dev Change the address, that can withdraw the rewards of a delegator. 42 | /// Note that this address cannot be a module account. 43 | /// @param delegatorAddress The address of the delegator 44 | /// @param withdrawerAddress The address that will be capable of withdrawing rewards for 45 | /// the given delegator address 46 | function setWithdrawAddress( 47 | address delegatorAddress, 48 | string memory withdrawerAddress 49 | ) external returns (bool success); 50 | 51 | /// @dev Withdraw the rewards of a delegator from a validator 52 | /// @param delegatorAddress The address of the delegator 53 | /// @param validatorAddress The address of the validator 54 | /// @return amount The amount of Coin withdrawn 55 | function withdrawDelegatorRewards( 56 | address delegatorAddress, 57 | string memory validatorAddress 58 | ) external returns (Coin[] calldata amount); 59 | 60 | /// @dev Withdraws the rewards commission of a validator. 61 | /// @param validatorAddress The address of the validator 62 | /// @return amount The amount of Coin withdrawn 63 | function withdrawValidatorCommission( 64 | string memory validatorAddress 65 | ) external returns (Coin[] calldata amount); 66 | 67 | /// QUERIES 68 | /// @dev Queries validator commission and self-delegation rewards for validator. 69 | /// @param validatorAddress The address of the validator 70 | /// @return distributionInfo The validator's distribution info 71 | function validatorDistributionInfo( 72 | string memory validatorAddress 73 | ) 74 | external 75 | view 76 | returns ( 77 | ValidatorDistributionInfo calldata distributionInfo 78 | ); 79 | 80 | /// @dev Queries the outstanding rewards of a validator address. 81 | /// @param validatorAddress The address of the validator 82 | /// @return rewards The validator's outstanding rewards 83 | function validatorOutstandingRewards( 84 | string memory validatorAddress 85 | ) external view returns (DecCoin[] calldata rewards); 86 | 87 | /// @dev Queries the accumulated commission for a validator. 88 | /// @param validatorAddress The address of the validator 89 | /// @return commission The validator's commission 90 | function validatorCommission( 91 | string memory validatorAddress 92 | ) external view returns (DecCoin[] calldata commission); 93 | 94 | /// @dev Queries the slashing events for a validator in a given height interval 95 | /// defined by the starting and ending height. 96 | /// @param validatorAddress The address of the validator 97 | /// @param startingHeight The starting height 98 | /// @param endingHeight The ending height 99 | /// @param pageRequest Defines a pagination for the request. 100 | /// @return slashes The validator's slash events 101 | /// @return pageResponse The pagination response for the query 102 | function validatorSlashes( 103 | string memory validatorAddress, 104 | uint64 startingHeight, 105 | uint64 endingHeight, 106 | PageRequest calldata pageRequest 107 | ) 108 | external 109 | view 110 | returns ( 111 | ValidatorSlashEvent[] calldata slashes, 112 | PageResponse calldata pageResponse 113 | ); 114 | 115 | /// @dev Queries the total rewards accrued by a delegation from a specific address to a given validator. 116 | /// @param delegatorAddress The address of the delegator 117 | /// @param validatorAddress The address of the validator 118 | /// @return rewards The total rewards accrued by a delegation. 119 | function delegationRewards( 120 | address delegatorAddress, 121 | string memory validatorAddress 122 | ) external view returns (DecCoin[] calldata rewards); 123 | 124 | /// @dev Queries the total rewards accrued by each validator, that a given 125 | /// address has delegated to. 126 | /// @param delegatorAddress The address of the delegator 127 | /// @return rewards The total rewards accrued by each validator for a delegator. 128 | /// @return total The total rewards accrued by a delegator. 129 | function delegationTotalRewards( 130 | address delegatorAddress 131 | ) 132 | external 133 | view 134 | returns ( 135 | DelegationDelegatorReward[] calldata rewards, 136 | DecCoin[] calldata total 137 | ); 138 | 139 | /// @dev Queries all validators, that a given address has delegated to. 140 | /// @param delegatorAddress The address of the delegator 141 | /// @return validators The addresses of all validators, that were delegated to by the given address. 142 | function delegatorValidators( 143 | address delegatorAddress 144 | ) external view returns (string[] calldata validators); 145 | 146 | /// @dev Queries the address capable of withdrawing rewards for a given delegator. 147 | /// @param delegatorAddress The address of the delegator 148 | /// @return withdrawAddress The address capable of withdrawing rewards for the delegator. 149 | function delegatorWithdrawAddress( 150 | address delegatorAddress 151 | ) external view returns (string memory withdrawAddress); 152 | 153 | /// @dev SetWithdrawerAddress defines an Event emitted when a new withdrawer address is being set 154 | /// @param caller the caller of the transaction 155 | /// @param withdrawerAddress the newly set withdrawer address 156 | event SetWithdrawerAddress( 157 | address indexed caller, 158 | string withdrawerAddress 159 | ); 160 | 161 | /// @dev WithdrawDelegatorRewards defines an Event emitted when rewards from a delegation are withdrawn 162 | /// @param delegatorAddress the address of the delegator 163 | /// @param validatorAddress the address of the validator 164 | /// @param amount the amount being withdrawn from the delegation 165 | event WithdrawDelegatorRewards( 166 | address indexed delegatorAddress, 167 | string indexed validatorAddress, 168 | uint256 amount 169 | ); 170 | 171 | /// @dev WithdrawValidatorCommission defines an Event emitted when validator commissions are being withdrawn 172 | /// @param validatorAddress is the address of the validator 173 | /// @param commission is the total commission earned by the validator 174 | event WithdrawValidatorCommission( 175 | string indexed validatorAddress, 176 | uint256 commission 177 | ); 178 | } 179 | -------------------------------------------------------------------------------- /precompiles/stateful/ICS20.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: LGPL-3.0-only 2 | pragma solidity >=0.8.18; 3 | 4 | import "../common/Types.sol"; 5 | import "../common/IICS20Authorization.sol"; 6 | 7 | /// @dev The ICS20I contract's address. 8 | address constant ICS20_PRECOMPILE_ADDRESS = 0x0000000000000000000000000000000000000802; 9 | 10 | /// @dev The ICS20 contract's instance. 11 | ICS20I constant ICS20_CONTRACT = ICS20I(ICS20_PRECOMPILE_ADDRESS); 12 | 13 | /// @dev DenomTrace contains the base denomination for ICS20 fungible tokens and the 14 | /// source tracing information path. 15 | struct DenomTrace { 16 | // path defines the chain of port/channel identifiers used for tracing the 17 | // source of the fungible token. 18 | string path; 19 | // base denomination of the relayed fungible token. 20 | string baseDenom; 21 | } 22 | 23 | /// @author Evmos Team 24 | /// @title ICS20 Transfer Precompiled Contract 25 | /// @dev The interface through which solidity contracts will interact with IBC Transfer (ICS20) 26 | /// @custom:address 0x0000000000000000000000000000000000000802 27 | interface ICS20I is IICS20Authorization { 28 | /// @dev Emitted when an ICS-20 transfer is executed. 29 | /// @param sender The address of the sender. 30 | /// @param receiver The address of the receiver. 31 | /// @param sourcePort The source port of the IBC transaction. 32 | /// @param sourceChannel The source channel of the IBC transaction. 33 | /// @param denom The denomination of the tokens transferred. 34 | /// @param amount The amount of tokens transferred. 35 | /// @param memo The IBC transaction memo. 36 | event IBCTransfer( 37 | address indexed sender, 38 | string indexed receiver, 39 | string sourcePort, 40 | string sourceChannel, 41 | string denom, 42 | uint256 amount, 43 | string memo 44 | ); 45 | 46 | /// @dev Transfer defines a method for performing an IBC transfer. 47 | /// @param sourcePort the port on which the packet will be sent 48 | /// @param sourceChannel the channel by which the packet will be sent 49 | /// @param denom the denomination of the Coin to be transferred to the receiver 50 | /// @param amount the amount of the Coin to be transferred to the receiver 51 | /// @param sender the hex address of the sender 52 | /// @param receiver the bech32 address of the receiver 53 | /// @param timeoutHeight the timeout height relative to the current block height. The timeout is disabled when set to 0 54 | /// @param timeoutTimestamp the timeout timestamp in absolute nanoseconds since unix epoch. The timeout is disabled when set to 0 55 | /// @param memo optional memo 56 | /// @return nextSequence sequence number of the transfer packet sent 57 | function transfer( 58 | string memory sourcePort, 59 | string memory sourceChannel, 60 | string memory denom, 61 | uint256 amount, 62 | address sender, 63 | string memory receiver, 64 | Height memory timeoutHeight, 65 | uint64 timeoutTimestamp, 66 | string memory memo 67 | ) external returns (uint64 nextSequence); 68 | 69 | /// @dev DenomTraces Defines a method for returning all denom traces. 70 | /// @param pageRequest Defines the pagination parameters to for the request. 71 | function denomTraces( 72 | PageRequest memory pageRequest 73 | ) 74 | external 75 | view 76 | returns ( 77 | DenomTrace[] memory denomTraces, 78 | PageResponse memory pageResponse 79 | ); 80 | 81 | /// @dev DenomTrace defines a method for returning a denom trace. 82 | function denomTrace( 83 | string memory hash 84 | ) external view returns (DenomTrace memory denomTrace); 85 | 86 | /// @dev DenomHash defines a method for returning a hash of the denomination trace info. 87 | function denomHash( 88 | string memory trace 89 | ) external view returns (string memory hash); 90 | 91 | } -------------------------------------------------------------------------------- /precompiles/stateful/Staking.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: LGPL-3.0-only 2 | pragma solidity >=0.8.17; 3 | 4 | import "../common/Authorization.sol" as authorization; 5 | import "../common/Types.sol"; 6 | 7 | 8 | /// @dev The StakingI contract's address. 9 | address constant STAKING_PRECOMPILE_ADDRESS = 0x0000000000000000000000000000000000000800; 10 | 11 | /// @dev The StakingI contract's instance. 12 | StakingI constant STAKING_CONTRACT = StakingI(STAKING_PRECOMPILE_ADDRESS); 13 | 14 | /// @dev Define all the available staking methods. 15 | string constant MSG_DELEGATE = "/cosmos.staking.v1beta1.MsgDelegate"; 16 | string constant MSG_UNDELEGATE = "/cosmos.staking.v1beta1.MsgUndelegate"; 17 | string constant MSG_REDELEGATE = "/cosmos.staking.v1beta1.MsgBeginRedelegate"; 18 | string constant MSG_CANCEL_UNDELEGATION = "/cosmos.staking.v1beta1.MsgCancelUnbondingDelegation"; 19 | 20 | /// @dev Defines the initial commission rates to be used for creating 21 | /// a validator. 22 | struct CommissionRates { 23 | uint256 rate; 24 | uint256 maxRate; 25 | uint256 maxChangeRate; 26 | } 27 | 28 | /// @dev Defines commission parameters for a given validator. 29 | struct Commission { 30 | CommissionRates commissionRates; 31 | uint256 updateTime; 32 | } 33 | 34 | 35 | /// @dev Represents a validator in the staking module. 36 | struct Validator { 37 | string operatorAddress; 38 | string consensusPubkey; 39 | bool jailed; 40 | BondStatus status; 41 | uint256 tokens; 42 | uint256 delegatorShares; // TODO: decimal 43 | string description; 44 | int64 unbondingHeight; 45 | int64 unbondingTime; 46 | uint256 commission; 47 | uint256 minSelfDelegation; 48 | } 49 | 50 | struct RedelegationResponse { 51 | Redelegation redelegation; 52 | RedelegationEntryResponse[] entries; 53 | } 54 | 55 | struct Redelegation { 56 | string delegatorAddress; 57 | string validatorSrcAddress; 58 | string validatorDstAddress; 59 | RedelegationEntry[] entries; 60 | } 61 | 62 | struct RedelegationEntryResponse { 63 | RedelegationEntry redelegationEntry; 64 | uint256 balance; 65 | } 66 | 67 | struct RedelegationEntry { 68 | int64 creationHeight; 69 | int64 completionTime; 70 | uint256 initialBalance; 71 | uint256 sharesDst; // TODO: decimal 72 | } 73 | 74 | struct UnbondingDelegationEntry { 75 | int64 creationHeight; 76 | int64 completionTime; 77 | uint256 initialBalance; 78 | uint256 balance; 79 | } 80 | 81 | /// @dev The status of the validator. 82 | enum BondStatus { 83 | Unspecified, 84 | Unbonded, 85 | Unbonding, 86 | Bonded 87 | } 88 | 89 | /// @author Evmos Team 90 | /// @title Staking Precompiled Contract 91 | /// @dev The interface through which solidity contracts will interact with staking. 92 | /// We follow this same interface including four-byte function selectors, in the precompile that 93 | /// wraps the pallet. 94 | /// @custom:address 0x0000000000000000000000000000000000000800 95 | interface StakingI is authorization.AuthorizationI { 96 | /// @dev Defines a method for performing a delegation of coins from a delegator to a validator. 97 | /// @param delegatorAddress The address of the delegator 98 | /// @param validatorAddress The address of the validator 99 | /// @param amount The amount of the Coin to be delegated to the validator 100 | /// @return success Whether or not the delegate was successful 101 | function delegate( 102 | address delegatorAddress, 103 | string memory validatorAddress, 104 | uint256 amount 105 | ) external returns (bool success); 106 | 107 | /// @dev Defines a method for performing an undelegation from a delegate and a validator. 108 | /// @param delegatorAddress The address of the delegator 109 | /// @param validatorAddress The address of the validator 110 | /// @param amount The amount to be undelegated from the validator 111 | /// @return completionTime The time when the undelegation is completed 112 | function undelegate( 113 | address delegatorAddress, 114 | string memory validatorAddress, 115 | uint256 amount 116 | ) external returns (int64 completionTime); 117 | 118 | /// @dev Defines a method for performing a redelegation 119 | /// of coins from a delegator and source validator to a destination validator. 120 | /// @param delegatorAddress The address of the delegator 121 | /// @param validatorSrcAddress The validator from which the redelegation is initiated 122 | /// @param validatorDstAddress The validator to which the redelegation is destined 123 | /// @param amount The amount to be redelegated to the validator 124 | /// @return completionTime The time when the redelegation is completed 125 | function redelegate( 126 | address delegatorAddress, 127 | string memory validatorSrcAddress, 128 | string memory validatorDstAddress, 129 | uint256 amount 130 | ) external returns (int64 completionTime); 131 | 132 | /// @dev Allows delegators to cancel the unbondingDelegation entry 133 | /// and to delegate back to a previous validator. 134 | /// @param delegatorAddress The address of the delegator 135 | /// @param validatorAddress The address of the validator 136 | /// @param amount The amount of the Coin 137 | /// @param creationHeight The height at which the unbonding took place 138 | /// @return success Whether or not the unbonding delegation was cancelled 139 | function cancelUnbondingDelegation( 140 | address delegatorAddress, 141 | string memory validatorAddress, 142 | uint256 amount, 143 | uint256 creationHeight 144 | ) external returns (bool success); 145 | 146 | /// @dev Queries the given amount of the bond denomination to a validator. 147 | /// @param delegatorAddress The address of the delegator. 148 | /// @param validatorAddress The address of the validator. 149 | /// @return shares The amount of shares, that the delegator has received. 150 | /// @return balance The amount in Coin, that the delegator has delegated to the given validator. 151 | function delegation( 152 | address delegatorAddress, 153 | string memory validatorAddress 154 | ) external view returns (uint256 shares, Coin calldata balance); 155 | 156 | /// @dev Returns the delegation shares and coins, that are currently 157 | /// unbonding for a given delegator and validator pair. 158 | /// @param delegatorAddress The address of the delegator. 159 | /// @param validatorAddress The address of the validator. 160 | /// @return entries The delegations that are currently unbonding. 161 | function unbondingDelegation( 162 | address delegatorAddress, 163 | string memory validatorAddress 164 | ) external view returns (UnbondingDelegationEntry[] calldata entries); 165 | 166 | /// @dev Queries validator info for a given validator address. 167 | /// @param validatorAddress The address of the validator. 168 | /// @return validator The validator info for the given validator address. 169 | function validator( 170 | string memory validatorAddress 171 | ) external view returns (Validator calldata validator); 172 | 173 | /// @dev Queries all validators that match the given status. 174 | /// @param status Enables to query for validators matching a given status. 175 | /// @param pageRequest Defines an optional pagination for the request. 176 | function validators( 177 | string memory status, 178 | PageRequest calldata pageRequest 179 | ) 180 | external 181 | view 182 | returns ( 183 | Validator[] calldata validators, 184 | PageResponse calldata pageResponse 185 | ); 186 | 187 | /// @dev Queries all redelegations from a source to a destination validator for a given delegator. 188 | /// @param delegatorAddress The address of the delegator. 189 | /// @param srcValidatorAddress Defines the validator address to redelegate from. 190 | /// @param dstValidatorAddress Defines the validator address to redelegate to. 191 | /// @return entries The active redelegations for the given delegator, source and destination validator combination. 192 | function redelegation( 193 | address delegatorAddress, 194 | string memory srcValidatorAddress, 195 | string memory dstValidatorAddress 196 | ) external view returns (RedelegationEntry[] calldata entries); 197 | 198 | /// @dev Queries all redelegations based on the specified criteria: 199 | /// for a given delegator and/or origin validator address 200 | /// and/or destination validator address 201 | /// in a specified pagination manner. 202 | /// @param delegatorAddress The address of the delegator as string (can be a zero address). 203 | /// @param srcValidatorAddress Defines the validator address to redelegate from (can be empty string). 204 | /// @param dstValidatorAddress Defines the validator address to redelegate to (can be empty string). 205 | /// @param pageRequest Defines an optional pagination for the request. 206 | /// @return response Holds the redelegations for the given delegator, source and destination validator combination. 207 | function redelegations( 208 | address delegatorAddress, 209 | string memory srcValidatorAddress, 210 | string memory dstValidatorAddress, 211 | PageRequest calldata pageRequest 212 | ) 213 | external 214 | view 215 | returns ( 216 | RedelegationResponse[] calldata response, 217 | PageResponse calldata pageResponse 218 | ); 219 | 220 | /// @dev Delegate defines an Event emitted when a given amount of tokens are delegated from the 221 | /// delegator address to the validator address. 222 | /// @param delegatorAddress The address of the delegator 223 | /// @param validatorAddress The address of the validator 224 | /// @param amount The amount of Coin being delegated 225 | /// @param newShares The new delegation shares being held 226 | event Delegate( 227 | address indexed delegatorAddress, 228 | string indexed validatorAddress, 229 | uint256 amount, 230 | uint256 newShares 231 | ); 232 | 233 | /// @dev Unbond defines an Event emitted when a given amount of tokens are unbonded from the 234 | /// validator address to the delegator address. 235 | /// @param delegatorAddress The address of the delegator 236 | /// @param validatorAddress The address of the validator 237 | /// @param amount The amount of Coin being unbonded 238 | /// @param completionTime The time at which the unbonding is completed 239 | event Unbond( 240 | address indexed delegatorAddress, 241 | string indexed validatorAddress, 242 | uint256 amount, 243 | uint256 completionTime 244 | ); 245 | 246 | /// @dev Redelegate defines an Event emitted when a given amount of tokens are redelegated from 247 | /// the source validator address to the destination validator address. 248 | /// @param delegatorAddress The address of the delegator 249 | /// @param validatorSrcAddress The address of the validator from which the delegation is retracted 250 | /// @param validatorDstAddress The address of the validator to which the delegation is directed 251 | /// @param amount The amount of Coin being redelegated 252 | /// @param completionTime The time at which the redelegation is completed 253 | event Redelegate( 254 | address indexed delegatorAddress, 255 | string indexed validatorSrcAddress, 256 | string indexed validatorDstAddress, 257 | uint256 amount, 258 | uint256 completionTime 259 | ); 260 | 261 | /// @dev CancelUnbondingDelegation defines an Event emitted when a given amount of tokens 262 | /// that are in the process of unbonding from the validator address are bonded again. 263 | /// @param delegatorAddress The address of the delegator 264 | /// @param validatorAddress The address of the validator 265 | /// @param amount The amount of Coin that was in the unbonding process which is to be canceled 266 | /// @param creationHeight The block height at which the unbonding of a delegation was initiated 267 | event CancelUnbondingDelegation( 268 | address indexed delegatorAddress, 269 | string indexed validatorAddress, 270 | uint256 amount, 271 | uint256 creationHeight 272 | ); 273 | } 274 | -------------------------------------------------------------------------------- /precompiles/stateful/Vesting.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: LGPL-3.0-only 2 | pragma solidity >=0.8.18; 3 | 4 | import "../common/Types.sol"; 5 | 6 | /// @dev The VestingI contract's address. 7 | address constant VESTING_PRECOMPILE_ADDRESS = 0x0000000000000000000000000000000000000803; 8 | 9 | /// @dev The VestingI contract's instance. 10 | VestingI constant VESTING_CONTRACT = VestingI(VESTING_PRECOMPILE_ADDRESS); 11 | 12 | /// @dev Define all the available vesting methods. 13 | string constant MSG_CREATE_CLAWBACK_VESTING_ACCOUNT = "/evmos.vesting.v2.MsgCreateClawbackVestingAccount"; 14 | string constant MSG_FUND_VESTING_ACCOUNT = "/evmos.vesting.v2.MsgFundVestingAccount"; 15 | string constant MSG_CLAWBACK = "/evmos.vesting.v2.MsgClawback"; 16 | string constant MSG_CONVERT_VESTING_ACCOUNT = "/evmos.vesting.v2.MsgConvertVestingAccount"; 17 | string constant MSG_UPDATE_VESTING_FUNDER = "/evmos.vesting.v2.MsgUpdateVestingFunder"; 18 | 19 | // Period defines a length of time and amount of coins that will vest. 20 | struct Period { 21 | int64 length; 22 | Coin[] amount; 23 | } 24 | 25 | /// @author Evmos Team 26 | /// @title Vesting Precompiled Contract 27 | /// @dev The interface through which solidity contracts will interact with vesting. 28 | /// We follow this same interface including four-byte function selectors, in the precompile that 29 | /// wraps the pallet. 30 | /// @custom:address 0x0000000000000000000000000000000000000803 31 | interface VestingI { 32 | /// @dev This event is emitted when the allowance of a granter is set by a call to the approve method. 33 | /// The value field specifies the new allowance and the methods field holds the information for which methods 34 | /// the approval was set. 35 | /// @param grantee The contract address that received an Authorization from the granter. 36 | /// @param granter The account address that granted an Authorization. 37 | /// @param method The message type URL of the methods for which the approval is set. 38 | event Approval( 39 | address indexed grantee, 40 | address indexed granter, 41 | string method 42 | ); 43 | 44 | /// @dev Defines an event that is emitted when a clawback vesting account is created. 45 | /// @param funderAddress The address of the account that funded the vesting account. 46 | /// @param vestingAddress The address of the account that received the vesting account. 47 | event CreateClawbackVestingAccount( 48 | address indexed funderAddress, 49 | address indexed vestingAddress 50 | ); 51 | 52 | /// @dev Defines an event that is emitted when a clawback vesting account is funded. 53 | /// @param funderAddress The address of the account that funded the vesting account. 54 | /// @param vestingAddress The address of the account that received the vesting account. 55 | /// @param startTime The time at which the vesting account will start. 56 | /// @param lockupPeriods The lockup periods of the vesting account. 57 | /// @param vestingPeriods The vesting periods of the vesting account. 58 | event FundVestingAccount( 59 | address indexed funderAddress, 60 | address indexed vestingAddress, 61 | uint64 startTime, 62 | Period[] lockupPeriods, 63 | Period[] vestingPeriods 64 | ); 65 | 66 | /// @dev Defines an event that is emitted when a vesting account is clawed back. 67 | /// @param funderAddress The address of the account that funded the vesting account. 68 | /// @param accountAddress The address of the vesting account. 69 | /// @param destAddress The address of the account that received the clawed back coins. 70 | event Clawback( 71 | address indexed funderAddress, 72 | address indexed accountAddress, 73 | address destAddress 74 | ); 75 | 76 | /// @dev Defines an event that is emitted when a vesting account's funder is updated. 77 | /// @param funderAddress The address of the account that funded the vesting account. 78 | /// @param newFunderAddress The address of the new funder of the vesting account. 79 | /// @param vestingAddress The address of the vesting account. 80 | event UpdateVestingFunder( 81 | address indexed funderAddress, 82 | address indexed vestingAddress, 83 | address newFunderAddress 84 | ); 85 | 86 | /// @dev Defines an event that is emitted when a vesting account is converted to a clawback vesting account. 87 | /// @param vestingAddress The address of the vesting account. 88 | event ConvertVestingAccount( 89 | address indexed vestingAddress 90 | ); 91 | 92 | /// @dev Approves a list of Cosmos or IBC transactions with a specific amount of tokens. 93 | /// @param grantee The contract address which will have an authorization to spend the origin funds. 94 | /// @param method The message type URL of the method to approve. 95 | /// @return approved Boolean value to indicate if the approval was successful. 96 | function approve( 97 | address grantee, 98 | string calldata method 99 | ) external returns (bool approved); 100 | 101 | /// @dev Defines a method for creating a new clawback vesting account. 102 | /// @param funderAddress The address of the account that will fund the vesting account. 103 | /// @param vestingAddress The address of the account that will receive the vesting account. 104 | /// @param enableGovClawback If the vesting account will be subject to governance clawback. 105 | function createClawbackVestingAccount( 106 | address funderAddress, 107 | address vestingAddress, 108 | bool enableGovClawback 109 | ) external returns (bool success); 110 | 111 | /// @dev Defines a method for funding a vesting account. 112 | /// @param funderAddress The address of the account that will fund the vesting account. 113 | /// @param vestingAddress The address of the clawback vesting account that will receive the vesting funds. 114 | /// @param startTime The time at which the vesting account will start. 115 | /// @param lockupPeriods The lockup periods of the vesting account. 116 | /// @param vestingPeriods The vesting periods of the vesting account. 117 | function fundVestingAccount( 118 | address funderAddress, 119 | address vestingAddress, 120 | uint64 startTime, 121 | Period[] calldata lockupPeriods, 122 | Period[] calldata vestingPeriods 123 | ) external returns (bool success); 124 | 125 | /// @dev Defines a method for clawing back coins from a vesting account. 126 | /// @param funderAddress The address of the account that funded the vesting account. 127 | /// @param accountAddress The address of the vesting account. 128 | /// @param destAddress The address of the account that will receive the clawed back coins. 129 | function clawback( 130 | address funderAddress, 131 | address accountAddress, 132 | address destAddress 133 | ) external returns (Coin[] memory); 134 | 135 | /// @dev Defines a method for updating the funder of a vesting account. 136 | /// @param funderAddress The address of the account that funded the vesting account. 137 | /// @param newFunderAddress The address of the new funder of the vesting account. 138 | /// @param vestingAddress The address of the vesting account. 139 | function updateVestingFunder( 140 | address funderAddress, 141 | address newFunderAddress, 142 | address vestingAddress 143 | ) external returns (bool success); 144 | 145 | /// @dev Defines a method for converting a clawback vesting account to an eth account 146 | /// @param vestingAddress The address of the vesting account. 147 | function convertVestingAccount( 148 | address vestingAddress 149 | ) external returns (bool success); 150 | 151 | /// QUERIES 152 | 153 | /// @dev Defines a query for getting the balances of a vesting account. 154 | /// @param vestingAddress The address of the vesting account. 155 | function balances( 156 | address vestingAddress 157 | ) external view returns (Coin[] memory locked, Coin[] memory unvested, Coin[] memory vested); 158 | } -------------------------------------------------------------------------------- /precompiles/stateless/Bech32.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: LGPL-v3 2 | pragma solidity >=0.8.17; 3 | 4 | /// @dev The Bech32I contract's address. 5 | address constant Bech32_PRECOMPILE_ADDRESS = 0x0000000000000000000000000000000000000400; 6 | 7 | /// @author Evmos Team 8 | /// @title Bech32 Precompiled Contract 9 | /// @dev The interface through which solidity contracts can convert addresses from 10 | /// hex to bech32 and vice versa. 11 | /// @custom:address 0x0000000000000000000000000000000000000010 12 | interface Bech32I { 13 | /// @dev Defines a method for converting a hex formatted address to bech32. 14 | /// @param addr The hex address to be converted. 15 | /// @param prefix The human readable prefix (HRP) of the bech32 address. 16 | /// @return bech32Address The address in bech32 format. 17 | function hexToBech32( 18 | address addr, 19 | string memory prefix 20 | ) external returns (string memory bech32Address); 21 | 22 | /// @dev Defines a method for converting a bech32 formatted address to hex. 23 | /// @param bech32Address The bech32 address to be converted. 24 | /// @return addr The address in hex format. 25 | function bech32ToHex( 26 | string memory bech32Address 27 | ) external returns (address addr); 28 | } 29 | --------------------------------------------------------------------------------