---
# System prepended metadata

title: v13.0.0-rc2 Testnet Release Changes

---

# 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`.