# v13.0.0-rc2 Testnet Release Changes This document aims to outline some of the changes we are bringing to the upcoming `v13.0.0-rc2` testnet release. It's a general document for any smart contract developers but it's **particularly important for developers who have already deployed contracts to Testnet or are participanting in the [DoraHacks hackaton](https://dorahacks.io/hackathon/EVM)** as your contracts will break after this new testnet upgrade so please update them as soon as possible with the changes outlined in this document. ## Approvals ### Calling the extension directly from an EOA We have refactored the direct to extension calls from an EOA to **NOT** require authorization / grant so developers can directly create a transaction calling the extension. The extension addresses are listed below: ```go "0x0000000000000000000000000000000000000800", // Staking precompile "0x0000000000000000000000000000000000000801", // Distribution precompile "0x0000000000000000000000000000000000000802", // ICS20 transfer precompile ``` This change allows for frontend applications utilizing the extensions directly from an EOA to have a more streamlined UX. ## Calling the extension from a smart contract In the previous testnet we were using the `spender` in the approval interface incorrectly. We were always assuming the `spender` as the `msg.sender` or granter and hardcoding the `CallerAddress` as the grantee. We want to mimic the `IERC20` contract flow as closely as possible so now the `spender` will be the smart contract you want to authorize from the `origin` EOA signing the transaction. **The Interface** ```Solidity function approve( address spender, uint256 amount, string[] calldata methods ) external returns (bool approved); ``` **Before** You would pass the user or contract as `msg.sender` to the `spender` and assuming the contract to be the `spendee` ```Solidity contract StakingManager { string[] private stakingMethods = [MSG_DELEGATE, MSG_UNDELEGATE, MSG_REDELEGATE, MSG_CANCEL_UNDELEGATION]; function approveAllStakingMethodsWithMaxAmount() public { bool success = STAKING_CONTRACT.approve(msg.sender, type(uint256).max, stakingMethods); require(success, "Failed to approve staking methods"); } } ``` **With v13.0.0-rc2** Now the `spender` has to be the contract you are trying to authorize the `origin` against. The `origin` will always be hardcoded into the grant even if the contract hops calls. So a generally good practice is to always create an authorization to contract that calls into the extension. ```Solidity contract StakingManager { string[] private stakingMethods = [MSG_DELEGATE, MSG_UNDELEGATE, MSG_REDELEGATE, MSG_CANCEL_UNDELEGATION]; function approveAllStakingMethodsWithMaxAmount() public { bool success = STAKING_CONTRACT.approve(address(this), type(uint256).max, stakingMethods); require(success, "Failed to approve staking methods"); } } ``` ## New Distribution Authorization interface With `v13.0.0-rc2` we decided to extend the `distribution` module's authorization struct to include an `AllowedList` which represents the different addresses that can be used in each of the transactions present on the interface. **The Interface** You can find the full interface [HERE](https://github.com/evmos/extensions/blob/main/precompiles/common/DistributionAuthorization.sol) For the Cosmos SDK authz changes you can find the changes [HERE](https://github.com/evmos/cosmos-sdk/blob/e925a63f7961edda08f12efdfeb0a0bba49783f7/x/distribution/types/authz.go#L36-L62) ```Solidity function approve( address spender, string[] calldata methods, string[] calldata allowedList ) external returns (bool approved); ``` **Before** As with the staking authorization here we were passing the `msg.sender` as the spender which should be replaced with the contract address of the smart contract that will be calling into the extensions. Furthermore you will notice it only took 2 parameters namely the `spender` and the `methods`. ```Solidity function _approveRequiredMsgs(uint256 _amount) internal { bool successDist = DISTRIBUTION_CONTRACT.approve(msg.sender, distributionMethods); require(successDist, "Distribution Approve failed"); } ``` **With v13.0.0-rc2** The new interface now enforces the correct `spender` parameter to be the contract address and hardcodes the `tx.origin` as the `spendee`. Additionally there is a new parameter `allowedList` which will always include the `tx.origin` if it is not passed in manually. ```Solidity function _approveRequiredMsgs(uint256 _amount) internal { string[] memory allowedList = new string[](0); // Will always add tx.origin address if it's not passed in manually bool successDist = DISTRIBUTION_CONTRACT.approve(address(this), distributionMethods, allowedList); require(successDist, "Distribution Approve failed"); } ``` **The Allowed List in transactions** Below is outlined what you can expect when passing addresses in the `allowedList` parameter in terms of effects on the transactions in `distribution` 1. `MsgSetWithdrawAddress` - if you wish to change the withdraw address for a user the new `withdrawerAddress` should be present in the `allowedList`.