---
# System prepended metadata

title: Deposit refunds

---

# Deposit refunds

On [Recoverable app funds](https://hackmd.io/JM6xBeOGQPCgUeXqnCUR9A), we  designed a system that would enable users to withdraw funds from a finalized state after an application is foreclosed. Now, we want to enable users to request a refund for a deposit that was not finalized in any state after the application foreclosure. This would be possible with the addition of the following definitions to the application contract interface.

```solidity
// interface IApplication { ...
event RefundIssued(uint256 inputIndex, bytes input, bytes output);
error DataAvailabilityIsNotInputBox();
error InvalidInputIndex();
error InvalidInput();
error CannotRefundFinalizedInput();
error RefundAlreadyIssued();
error NotDepositInput();
function getNumberOfIssuedRefunds() external view returns (uint256);
function wasRefundIssued(uint256 inputIndex) external view returns (bool);
function validateInput(uint256 inputIndex, bytes calldata input) external view;
function issueRefund(uint256 inputIndex, bytes calldata input) external;
// }
```

Similar to withdrawals, we make the action transparent through an output that, once executed, performs the asset transfer back to the user. This allows front-ends to describe more precisely what happened when the user pressed the withdrawal/refund button. We also create a refund output buider contract, with the following function signature. Internally, it matches the input sender against a list of known portal addresses, decodes the payload, and returns an output that, once executed, refunds the user.

```solidity
// interface IRefundOutputBuilder { ...
function buildRefundOutput(
    address appContract,
    address sender,
    bytes calldata payload
) external view returns (bytes output);
// }
```

The application contract will check whether the input was processed or not by calling a new function in the outputs Merkle root validator interface:

```solidity
// interface IOutputsMerkleRootValidator { ...
function wasInputFinalized(
    address appContract,
    uint256 inputIndex,
    uint256 blockNumber
) external view returns (bool);
// }
```

This function, in turn, would decode the input, and check either its index (in the case of PRT) or its block number (in the case of Authority and Quorum) to determined whether the input was finalized or not. The application contract address would also be extracted from the input metadata.

The address of this refund output builder contract would be included in the withdrawal config parameter passed down to application deployment entrypoints.

```solidity
// struct WithdrawalConfig { ...
IRefundOutputBuilder refundOutputBuilder;
// }
```

And this address would be accessible through a new view function on the application interface.

```solidity
// interface IApplication { ...
function getRefundOutputBuilder() external view returns (IRefundOutputBuilder);
// }
```