#Should the token contract have a create_trustline method?

44 messages · Page 1 of 1 (latest)

red gale
#

When working with a token recently, I did the following:

$ soroban lab token wrap --network futurenet --source default --asset "EXT:$(soroban config identity address default)"
SUCCESS
b528a3f9235cc912c64e5a07d78ec5d634d8be46cde582f9298d337406ecfd5c

$ soroban contract invoke \
    --network futurenet \
    --source default \
    --id b528a3f9235cc912c64e5a07d78ec5d634d8be46cde582f9298d337406ecfd5c \
    -- \
    xfer \
    --to $FREIGHTER_ADDRESS \
    --from $(soroban config identity address default) \
    --amount 100
error: transaction simulation failed: HostError
Value: Status(ContractError(13))

Debug events (newest first):
   0: "Debug trustline missing"
[...]

This makes sense, as the freighter wallet I was sending the tokens to has no trustline for this asset. But afaict there's not really a way to create the trustline from freighter or soroban-cli (without writing code).

Maybe laboratory could help, or maybe we should add a subcommand to soroban-cli, but, this got me thinking about a wider scenario of "send a new token to the user". This would be common in the case of any on-chain swaps where you deposit X and receive new token Y in exchange.

Currently for this scenario, you'd need to do two transactions:

  1. create trustline for Y with a classic op.
  2. call the swap contract to do the swap: e.g. pool.swap(x, y)

This is a similar flow to the old approve&transfer_from workflow which auth-next helps us avoid.

Proposal 1

Should the standard asset contract have an create_trustline(user, asset) method?

It could idempotently ensure that the user has a trustline for the given asset, and could be callable only by user.

In that case auth-next would allow the pool.swap(x, y) to call create_trustline on behalf of the user with delegation, like the tranfer_from workflow is now.

Proposal 2

More radical suggestion: Should transfer and transfer_from auto-create a trustline?

night folio
#

Auto creating the trustline would break the existing opt-in behavior with classic assets.

Proposal 1 would work, but I don't think it's necessary or a good idea since the classic op exists. Duplicating that logic in the token contract may make the flow a little simpler (I'm not actually sure about this since it'll require multiple signers), but I don't think it's worth the maintenance burden of having even more classic logic in Soroban. This would be the only case of a non-Soroban entry being created in Soroban, requiring us to duplicate the base reserve charging logic.

red gale
#

I don't think it's necessary or a good idea since the classic op exists
But you could say that about the entire standard asset contract. Classic transfer op also exists.

night folio
#

Without the transfer function, there's no way to use classic stellar assets in Soroban. That functionality was the minimum required to move value into Soroban.

#

All of the classic functionality in the SAC is pretty much the minimum required to use classic assets in Soroban without breaking any asset authorization rules set in classic.

bronze schooner
#

I think adding a function makes sense. Maybe name the function simply trust, which an address can call, and which creates a trustline. Stellar Asset Contracts are tokens, but they have additional functionality that a holder has to trust the contract before it can hold. I think it's fine for us to add functions to it that don't exist in the standard token contract interface, other custom tokens will do the same too.

pliant bane
#

i kind of like the idea of the create_trustline method

lone mountain
#

I think it's fine for us to add functions to it that don't exist in the standard token contract interface, other custom tokens will do the same too.
this kind of defeats the purpose of having token interface

#

this would basically lock the contracts into SAC only

#

while we've tried really hard to abstract this logic away

#

is it impossible to just move this logic off-chain and propose the users to create the trustlines under certain conditions?

#

this really doesn't seem like something the contracts should ever do - this is pretty abusable

bronze schooner
#

this kind of defeats the purpose of having token interface
this would basically lock the contracts into SAC only
Adding the function doesn't mean contracts need to use it, but it does mean that the soroban-cli and other tools can call the fn directly.

#

while we've tried really hard to abstract this logic away
We haven't really abstracted it, we've hidden it. If we'd abstracted it, it would be possible to trust a SAC without needing to know you need to trust it.

lone mountain
#

I don't quite agree. trust is the implementation detail

#

soroban-cli and other tools can call the classic operation directly as well

bronze schooner
#

Maybe there's some things we could do to try and discourage folks from calling trust in a contract.

bronze schooner
#

E.g. A user can't trust, act, then untrust.

lone mountain
#

is that really that big of a problem? adding trustlines should be a one-off operation

bronze schooner
#

We have trust-act-untrust in flows, in SEPs. We should consider if that's an important use case to support.

lone mountain
#

hmm, I'm not familiar with that

#

what is the purpose of such flows?

bronze schooner
lone mountain
#

the concept of trustline is built around the conscious user decision of adding another asset to their account (not for free as well; the reserve cost is IIUC much higher than the typical transaction fee). doing that programmatically from an unrelated contract seems problematic

bronze schooner
#

I meant composition in the sense that a user trusts, acts, then unstrusts at the top level, not from a contract.

lone mountain
#

also it would need to be accompanied by need_trust or something, otherwise you'd require user to sign trust every time the contract is called...

bronze schooner
#

What is need_trust?

lone mountain
#

btw the auth flow is supported by set_authorization, unless I'm mistaken

#

the function that would check if the address needs a trustline...

#

the trustline creation is also quite problematic from the fee standpoint as well; we'd need to special-case it (currently soroban doesn't ever create any classic entries, it can only modify them and thus doesn't need to deal with the reserve)

pliant bane
#

See the reason I've been thinking of this is for minting new assets in soroban that are immediately compatible with classic trustline. I guess it might not be needed but it'd still be nice to have

vital rune
#

I think (from a user experience standpoint) that the tools should include the query for trustline and to be able to debug trustlines. The minimum viable product probably needs to tell them where to find documentation on how to create the trustline from within the CLI. I struggled with the CLI because it pretended a lot of information was self evident. ``` bindings Generate code client bindings for a contract
deploy Deploy a contract
inspect Inspect a WASM file listing contract functions, meta, etc
install Install a WASM file to the ledger without creating a contract instance
invoke Invoke a contract function
optimize Optimize a WASM file
read Print the current value of a contract-data ledger entry

Deploy is the deploy button which does a deploy. Is that a compile? is it published on chain? The help says neither.  Since install doesn't create an instance, which command does? Apparently none! From a UX perspective, the tools should be more self documenting, and the proposal of trustline inclusion should probably adhere to that goal of self documenting and self contained tools.
forest walrus
lone mountain
#

how are trustlines handled in classic?

forest walrus
lone mountain
#

since establishing a trustline is a one-off task, I would actually expect a separate flow for that; it should be unrelated to soroban at least in dapp scope (it's ok to have for convenience in CLI)

turbid quartz
#

if the trustline end up being added to Soroban, I would like to have a way to avoid a contract auto trusting a new asset without my consent. I feel trustlines should stay as a separated operation, at the end of the day that's for classic assets only

pliant bane
#

right but in a sac contract that's meant to be interop with a normal asset

pliant bane
# lone mountain how are trustlines handled in classic?

an account opens a trustline to an assetname/issueraccount => the issuer account sends a payment to the account who opened the trustline. This is how a token is minted in "classic". Then also any account which holds the asset needs to 'trust' the asset.

Trust is established through a change trust operation. If the asset is authorization required, the issuer needs to do an "allow trust" operation to allow the account to open the trustline.

I agree it can be handled as a seperate transaction in a dapp; but it adds the inconvenience of the user having to sign another transaction... It really only seems relevant if you want your asset to exist on both classic and soroban

#

it's just slightly confusing having two sets of assets; We seem to be using the sac as a 'standard' token, but authorization is obviously handled differently on soroban; but what if someone has a sac token never minted on 'classic'. One concern to me is like after the issuer mints it with a trustline, and if it was already created on soroban, then what about the authorization flags, authorization seems to work different in smart contracts.

#

those are my naive thoughts thanks

red gale