-
Notifications
You must be signed in to change notification settings - Fork 9
How Polytone Supports Outposts
This page describes a feature we have removed from Polytone. Its left up for historical purposes.
With Polytone, users have one account for themselves, and one account with each outpost they interact with.
Why? Consider the listing flow for listing a NFT on Stargaze using Polytone:
During step (4), the Outpost needs to execute a message on the user's behalf, as it is info.sender
on the NFT Listing message. To allow for this, Note modules may be configured with a controller, there are two rules about controllers:
- Only the controller may execute messages on the Note module.
- The controller can set the message sender to whomever they'd like.
As a result of the first rule, outposts that are controllers can execute messages on user's behalves, making step (4) possible.
The second rule means that user's outpost accounts can be entirely separate from their regular accounts. This is useful because:
- An outpost can be deployed without a polytone deployment, because rule one scopes message execution to ones the outpost allows.
- A security vulnerability in the outpost will not impact a user's main remote account.
I suspect this will allow for very safe outpost configurations.
The goal of outposts is to provide an easy way for other chains to interact with the home chain. Polytone does most of this work as, for actions that do not require a token transfer, users get async message execution on the remote chain. For actions that do require a token transfer, an outpost is required as the ICS-20 and ICS-721 standards do not specify a way to transfer tokens and do an action once those tokens have been transferred. Outposts are then needed, as they can abstract a transfer, then callback, then action flow into one message from the user's perspective.
For token-transfer actions like swapping or selling, outposts can set the receiver to a user's regular Polytone account (or ICA account!), and then don't need to expose any non-token-related actions in their API!
For example, because Stargaze only requires a NFT to be sent to list one, the only thing a Stargaze outpost needs to be able to do is NFT listing. For all other actions, a user can use their regular Polytone account[^1].
In summary, outposts built with Polytone:
- Can IBC transfer tokens and perform an action on transfer completion like ICS-999.
- Don't require the remote chain make Polytone its default interchain accounts system.
- Can be written with very well scoped security permissions.
[^1]: and let me tell you, Polytone is good. Worry not about protobuf encoding or ICA's lack of callbacks. Just execute regular CosmWasm messages and get a callback when they're done. From the perspective of smart contract authors, this is the exact same pattern as CosmWasm's submessages and replies.
From the PR that removed it:
The controller was designed to support atomic token transfer and action on a remote chain. It has two rules:
If a note has a controller, only the controller may execute messages. The controller may specify an arbitrary sender when executing messages. The result of this is:
Users have two accounts: their outpost account, and their regular Polytone account. The security level of the outpost account is the security level of the outpost, as the outpost is the controller. While this works, it's not the greatest. Having two accounts isn't perfect UX, and handing off account security to another contract "feels" bad. Oak Security also classified this as a "major" issue in their audit report, saying that the requirement that Outposts are given unrestricted access to user accounts was quite sub-optimal.
The solution to this problem is non-obvious and complex. In their audit report, Oak suggests requiring the outpost user to pre-authorize a message for execution by the Outpost later. This doesn't work because not all of the information needed to create the second message is guarenteed to be avaliable at the time the first message is to be executed. For example, a transfer message can't be pre-crafted for a NFT collection being transfered to a remote chain for the first time, as the address of the NFT collection smart contract does not yet exist.
To resolve this, one could design some system wherein a transfer is pre-authorized for any non-existant denomination, or perhaps there are better schemes. Unfourtunately, schemes of this type belongs in the outpost code, not Polytone, as it requires custom code per token-type.
What a strange loop. Starting at from the permise of how to remove the controller, we arrive at the conclusion that we need the controller.
So why remove it? I am unsatisfied with this conclusion, the controller is a blemish on an otherwise simple and beautiful codebase, and off-chain it has become clear that we won't be building an outpost with Polytone in the near future.