# Distribution

### Solidity Interface & ABI[​](https://docs.evmos.org/develop/smart-contracts/evm-extensions/distribution#solidity-interface--abi) <a href="#solidity-interface--abi" id="solidity-interface--abi"></a>

`Distribution.sol` is an interface through which Solidity contracts can interact with Cosmos SDK distribution. This is convenient for developers as they don’t need to know the implementation details behind the `x/distribution` module in the Cosmos SDK. Instead, they can interact with distribution functions using the Ethereum interface they are familiar with.

#### Interface `Distribution.sol`[​](https://docs.evmos.org/develop/smart-contracts/evm-extensions/distribution#interface-distributionsol) <a href="#interface-distributionsol" id="interface-distributionsol"></a>

Find the [Solidity interface in the evmos/extensions repo](https://github.com/evmos/extensions/blob/main/precompiles/stateful/Distribution.sol).

#### ABI[​](https://docs.evmos.org/develop/smart-contracts/evm-extensions/distribution#abi) <a href="#abi" id="abi"></a>

Find the [ABI in the evmos/extensions repo](https://github.com/evmos/extensions/blob/main/precompiles/abi/distribution.json).

### Transactions[​](https://docs.evmos.org/develop/smart-contracts/evm-extensions/distribution#transactions) <a href="#transactions" id="transactions"></a>

* `setWithdrawAddress`

  ```
  /// @dev Change the address, that can withdraw the rewards of a delegator.
  /// Note that this address cannot be a module account.
  /// @param delegatorAddress The address of the delegator
  /// @param withdrawerAddress The address that will be capable of withdrawing rewards for
  /// the given delegator address
  function setWithdrawAddress(
      address delegatorAddress,
      string memory withdrawerAddress
  ) external returns (bool success);
  ```
* `withdrawDelegatorRewards`

  ```
  /// @dev Withdraw the rewards of a delegator from a validator
  /// @param delegatorAddress The address of the delegator
  /// @param validatorAddress The address of the validator
  /// @return amount The amount of Coin withdrawn
  function withdrawDelegatorRewards(
      address delegatorAddress,
      string memory validatorAddress
  )
  external
  returns (
      Coin[] calldata amount
  );
  ```
* `withdrawValidatorCommission`

  ```
  /// @dev Withdraws the rewards commission of a validator.
  /// @param validatorAddress The address of the validator
  /// @return amount The amount of Coin withdrawn
  function withdrawValidatorCommission(
      string memory validatorAddress
  )
  external
  returns (
      Coin[] calldata amount
  );
  ```

### Queries[​](https://docs.evmos.org/develop/smart-contracts/evm-extensions/distribution#queries) <a href="#queries" id="queries"></a>

* `validatorDistribution`

  ```
  /// @dev Queries validator commission and self-delegation rewards for validator.
  /// @param validatorAddress The address of the validator
  /// @return distributionInfo The validator's distribution info
  function validatorDistributionInfo(
      string memory validatorAddress
  )
  external
  view
  returns (
      ValidatorDistributionInfo[] calldata distributionInfo
  );
  ```
* `validatorOutstandingRewards`

  ```
  /// @dev Queries the outstanding rewards of a validator address.
  /// @param validatorAddress The address of the validator
  /// @return rewards The validator's outstanding rewards
  function validatorOutstandingRewards(
      string memory validatorAddress
  )
  external
  view
  returns (
      DecCoin[] calldata rewards
  );
  ```
* `validatorCommission`

  ```
  /// @dev Queries the accumulated commission for a validator.
  /// @param validatorAddress The address of the validator
  /// @return commission The validator's commission
  function validatorCommission(
      string memory validatorAddress
  )
  external
  view
  returns (
      DecCoin[] calldata commission
  );
  ```
* `validatorSlashes`

  ```
  /// @dev Queries the slashing events for a validator in a given height interval
  /// defined by the starting and ending height.
  /// @param validatorAddress The address of the validator
  /// @param startingHeight The starting height
  /// @param endingHeight The ending height
  /// @return slashes The validator's slash events
  /// @return pageResponse The pagination response for the query
  function validatorSlashes(
      string memory validatorAddress,
      uint64 startingHeight,
      uint64 endingHeight
  )
  external
  view
  returns (
      ValidatorSlashEvent[] calldata slashes,
      PageResponse calldata pageResponse
  );
  ```
* `delegationRewards`

  ```
  /// @dev Queries the total rewards accrued by a delegation from a specific address to a given validator.
  /// @param delegatorAddress The address of the delegator
  /// @param validatorAddress The address of the validator
  /// @return rewards The total rewards accrued by a delegation.
  function delegationRewards(
      address delegatorAddress,
      string memory validatorAddress
  )
  external
  view
  returns (
      DecCoin[] calldata rewards
  );
  ```
* `delegationTotalRewards`

  ```
  /// @dev Queries the total rewards accrued by each validator, that a given
  /// address has delegated to.
  /// @param delegatorAddress The address of the delegator
  /// @return rewards The total rewards accrued by each validator for a delegator.
  /// @return total The total rewards accrued by a delegator.
  function delegationTotalRewards(
      address delegatorAddress
  )
  external
  view
  returns (
      DelegationDelegatorReward[] calldata rewards,
      DecCoin[] calldata total
  );
  ```
* `delegatorValidators`

  ```
  /// @dev Queries all validators, that a given address has delegated to.
  /// @param delegatorAddress The address of the delegator
  /// @return validators The addresses of all validators, that were delegated to by the given address.
  function delegatorValidators(
      address delegatorAddress
  ) external view returns (string[] calldata validators);
  ```
* `delegatorWithdrawAddress`

  `delegatorWithdrawAddress` queries withdraw address of a delegator

  ```
  /// @dev Queries the address capable of withdrawing rewards for a given delegator.
  /// @param delegatorAddress The address of the delegator
  /// @return withdrawAddress The address capable of withdrawing rewards for the delegator.
  function delegatorWithdrawAddress(
      address delegatorAddress
  ) external view returns (string memory withdrawAddress);
  ```

### Events[​](https://docs.evmos.org/develop/smart-contracts/evm-extensions/distribution#events) <a href="#events" id="events"></a>

Each of the transactions emits its corresponding event. These are:

* `SetWithdrawerAddress`

  ```
  /// @dev SetWithdrawerAddress defines an Event emitted when a new withdrawer address is being set
  /// @param caller the caller of the transaction
  /// @param withdrawerAddress the newly set withdrawer address
  event SetWithdrawerAddress(
      address indexed caller,
      string withdrawerAddress
  );
  ```
* `WithdrawDelegatorRewards`

  ```
  /// @dev WithdrawDelegatorRewards defines an Event emitted when rewards from a delegation are withdrawn
  /// @param delegatorAddress the address of the delegator
  /// @param validatorAddress the address of the validator
  /// @param amount the amount being withdrawn from the delegation
  event WithdrawDelegatorRewards(
      address indexed delegatorAddress,
      string indexed validatorAddress,
      uint256 amount
  );
  ```
* `WithdrawValidatorCommission`

  ```
  /// @dev WithdrawValidatorCommission defines an Event emitted when validator commissions are being withdrawn
  /// @param validatorAddress is the address of the validator
  /// @param commission is the total commission earned by the validator
  event WithdrawValidatorCommission(
      string indexed validatorAddress,
      uint256 commission
  );
  ```

### Interact with the Solidity Interface[​](https://docs.evmos.org/develop/smart-contracts/evm-extensions/distribution#interact-with-the-solidity-interface) <a href="#interact-with-the-solidity-interface" id="interact-with-the-solidity-interface"></a>

Below are some examples of how to interact with this Solidity interface from your smart contracts.

Make sure to import the precompiled interface, e.g.:

```
import "https://github.com/financiyo/extensions/blob/main/precompiles/stateful/Distribution.sol";
```

#### Grant approval for the desired messages[​](https://docs.evmos.org/develop/smart-contracts/evm-extensions/distribution#grant-approval-for-the-desired-messages) <a href="#grant-approval-for-the-desired-messages" id="grant-approval-for-the-desired-messages"></a>

See below a function that grants approval to the smart contract to send all `x/distribution` module messages on behalf of the sender account. You can tweak this function to approve only the desired messages.

```
string[] private distributionMethods = [
    MSG_SET_WITHDRAWER_ADDRESS,
    MSG_WITHDRAW_DELEGATOR_REWARD,
    MSG_WITHDRAW_VALIDATOR_COMMISSION,
];

/// @dev Approves all distribution transactions.
/// @dev This creates a Cosmos Authorization Grant for the given methods.
/// @dev This emits an Approval event from the GenericAuthorization.sol.
function approveAllDistributionMethods() public {
    bool success = DISTRIBUTION_CONTRACT.approve(
        msg.sender,
        distributionMethods
    );
    require(success, "Failed to approve distribution methods");
}
```

#### Set withdraw address[​](https://docs.evmos.org/develop/smart-contracts/evm-extensions/distribution#set-withdraw-address) <a href="#set-withdraw-address" id="set-withdraw-address"></a>

The `changeWithdrawAddress` function allows a user to set a new withdraw address in the Cosmos `x/distribution` module. For this transaction to be successful, make sure the user had already approved the `MSG_SET_WITHDRAWER_ADDRESS` message.

```
function changeWithdrawAddress(
    string memory _withdrawAddr
) public returns (bool) {
    return
        distribution.DISTRIBUTION_CONTRACT.setWithdrawAddress(
            msg.sender,
            _withdrawAddr
        );
}
```

#### Withdraw staking rewards[​](https://docs.evmos.org/develop/smart-contracts/evm-extensions/distribution#withdraw-staking-rewards) <a href="#withdraw-staking-rewards" id="withdraw-staking-rewards"></a>

The `withdrawStakingRewards` function allows a user to withdraw his/her rewards corresponding to a specified validator. For this transaction to be successful, make sure the user had already approved the `MSG_WITHDRAW_DELEGATOR_REWARD` message.

```
    function withdrawStakingRewards(
    string memory _valAddr
) public returns (types.Coin[] memory) {
    return
        distribution.DISTRIBUTION_CONTRACT.withdrawDelegatorRewards(
            msg.sender,
            _valAddr
        );
}
```

#### Withdraw validator commission[​](https://docs.evmos.org/develop/smart-contracts/evm-extensions/distribution#withdraw-validator-commission) <a href="#withdraw-validator-commission" id="withdraw-validator-commission"></a>

If the user is running a validator, he/she could withdraw the corresponding commission using a smart contract. The user could use a function similar to `withdrawCommission`. For this transaction to be successful, make sure the user had already approved the `MSG_WITHDRAW_VALIDATOR_COMMISSION` message.

```
function withdrawCommission(
    string memory _valAddr
) public returns (types.Coin[] memory) {
    return
        distribution.DISTRIBUTION_CONTRACT.withdrawValidatorCommission(
            _valAddr
        );
}
```

#### Queries[​](https://docs.evmos.org/develop/smart-contracts/evm-extensions/distribution#queries-1) <a href="#queries-1" id="queries-1"></a>

Similarly to transactions, smart contracts can use query methods. To use these methods, there is no need for authorization, as these are read-only methods. Examples of this are the `getDelegationRewards` and `getValidatorCommision` functions that return the information for the specified validator address.

```
getDelegationRewards(
    string memory _valAddr
) public view returns (types.DecCoin[] memory) {
    return
        distribution.DISTRIBUTION_CONTRACT.delegationRewards(
            msg.sender,
            _valAddr
        );
}

function getValidatorCommission(
    string memory _valAddr
) public view returns (types.DecCoin[] memory) {
    return distribution.DISTRIBUTION_CONTRACT.validatorCommission(_valAddr);
}
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://financiyo.gitbook.io/docs/smart-contracts/evm-extensions/distribution.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
