Programs and Authorizations

A Valence Program is an instance of the Valence Protocol. It is a particular arrangement and configuration of accounts and libraries across multiple domains e.g. a POL (protocol-owned liquidity) lending relationship between two parties. Similarly to how a library exposes executable functions, programs are associated with a set of executable Subroutines.

A Subroutine is a vector of Functions. A Subroutine can call out to one or more function(s) from a single library, or from different ones. A Subroutine is limited to one execution domain (i.e. it cannot use functions from libraries instantiated on multiple domains).

A Subroutine can be:

  • Non Atomic, i.e., execute function one, if it succeeds execute function two, and if that succeeds do function three, and so on.
  • or Atomic, i.e., execution function one, function two, and function three, and if any of them fail then revert all steps.

Valence programs are typically used to implement complex, cross-chain workflows performing financial operations, in a trust-minimized way, on funds provided by various third-parties. Therefore, it goes without saying that a program's subroutines should not (all and/or always) be allowed to be executed by just about anyone.

To specify fine-grained controls over who can initiate the execution of a Subroutine, program creators use the Authorizations module.

The Authorizations module is a powerful and flexible system that supports simple to advanced access control configuration schemes, such as:

  • Anyone can initiate execution of a Subroutine
  • Only permissioned actors can initiate execution of a Subroutine
  • Execution can only be initiated after a starting timestamp/block height
  • Execution can only be initiated up to a certain timestamp/block height
  • Authorizations are tokenized, which means they can be transferred by the holder or used in more sophisticated DeFi scenarios
  • Authorizations can expire
  • Authorizations can be enabled/disabled
  • Authorizations can tightly constrain parameters. For example, an authorization to execute a token transfer message can limit the execution to only supply the amount argument, and not the denom or receiver in the transfer message

To support the on-chain execution of Valence Programs, the Valence Protocol provides two important contracts: the Authorizations contract and the Processor contract.

The Authorizations contract is the entry point for users. The user sends a set of messages to the Authorizations contract and the label (id) of the authorization they want to execute. The Authorizations contract then verifies that the sender is authorized, that the messages are valid, constructs a MessageBatch based on the subroutine and passes this batch to the Processor contract for execution. The authority to execute any Subroutine is tokenized so that these tokens can be transferred on-chain.

The Processor contract receives a MessageBatch and executes the contained Messages in sequence. It does this by maintaining execution queues, where the queue items are Subroutines. The processor exposes a Tick message that allows anyone to trigger the processor, whereby the first batch of the queue is executed or moved to the back of the queue if it's not executable yet (e.g. retry period has not passed).

graph LR;
	User --> |Subroutine| Auth(Authorizations)
	Auth --> |Message Batch| P(Processor)
	P --> |Function 1| S1[Library 1]
	P --> |Function 2| S2[Library 2]
	P --> |Function N| S3[Library N]