ERights Home elib / capability / ode 
Back to: As Game On to: Acknowledgements

From Capabilities To
Financial Instruments


From Stuff to Financial Instruments and Smart Contracts

Real world markets started out with direct trade of physical objects. To oversimplify greatly, ownership usually went along with possession and use, and, because of the locality of matter, all three together were exclusive. The user interface was intuitive -- you knew what rights you had because you could see your stuff. For Alice to transfer ownership of a cow to Bob, Alice and Bob would move the cow's physical location from Alice's territory to Bob's. Both would then effortlessly have common knowledge that the transfer had occurred, and who had which cows. Absent theft, possession would be an adequate record of ownership. Cows were bearer instruments. (There is some evidence that the first money was coins redeemable for cows [Selgin88].) Over time, of course, more abstract rights were invented, as were more complex arrangements for their transfer, usually with ghastly user interfaces and more room for misunderstandings and disputes.

A major aspect of the emergence of capitalism from feudalism was the rise of contract. By creating a contract, you could define and transfer an arbitrary bundle of rights. The complexity of trade could now bloom, unrestrained by the simple limits of physical matter. During the twentieth century, a great variety of financial instruments were invented. These instruments represent the discovery of many new kinds of rights, and ways of deriving these rights from more primitive rights. We should hope the growth of financial cryptography will only accelerate this trend. For this hope to be realized, we should seek not just the secure computational expression of the contracts representing existing instruments, but the creation of secure material from which similar new contracts can easily be built. Following Nick Szabo [Szabo97], we refer to a partially self-enforcing computational embodiment of a contract as a smart contract.

To understand the job ahead of us, we start by classifying the characteristics of rights.

A Taxonomy of Kinds of Rights

By contrasting some of the rights and rights-transfer mechanisms we have already seen -- capability-passing vs. SPKI certificates vs. our example money -- we can start to develop a taxonomy of rights. (Economics elaborates this taxonomy much more fully, but we will only present the subset relevant to this paper.)

  Capabilities SPKI Example Purse-Money

shareable vs. exclusive Alice shares with Bob her right to access Carol. Issuer shares with Subject the authorization to the Resource. When Bob deposits the payment from Alice, he knows he has excluded anyone else from using that money.

In the capability case, if Alice drops the capability after passing it to Bob, Bob happens to have exclusive access to Carol, but this isn't an exclusive right since Bob is unable to know that he is the only one who has it.

In the real world, information is sharable and physical objects are exclusive.
specific vs. fungible A capability designates a specific object. Authorization can be for specific objects, or for some number of units. Money is fungible, since we care only about quantity, not individual bills.
In the real world, real estate is specific and barrels of (a given grade of) oil are fungible. Peaches in the supermarket are specific -- you buy the ones you pick out. Peaches ordered over Peapod are fungible -- you order only by quantity.
opaque vs. assayable A capability is opaque, since from the capability alone all you can determine is what the designated object alleges about itself. An authorization can be read as well as used. Reading it may suffice to assay what value it would provide. Bob can reliably assay the amount in an alleged purse only by transferring into a purse he trusts.
Assayability is needed for trade, since you must be able to determine what you would be getting before deciding to purchase. However, exclusive rights can only be reliably assayed by actually obtaining exclusive access to them, since otherwise, after you've assayed them, someone else may gain the exclusive, cutting you out. Trade of exclusives may therefor require a trusted third party who can hold them in escrow.
exercisable vs. symbolic A capability has value only because it can be exercised, by sending a message to the object it designates. An authorization may be for either or both. As with fiat money, our example money is purely symbolic, since one can't do anything with it other than transfer it further.
There are many goods that are both exercisable and have symbolic value. For example, gold is commonly used as a pure symbol of value, but gold is also used to create electronic hardware and decorative jewelry.

It is curious that our example money is so different from capabilities, when the money is trivially built out of capabilities. More puzzling is the transfer. Alice passed to Bob only a capability, which therefor had all the rights-transfer properties of our first column. However, by doing so, she also paid him money, which has all the properties of the last column. Unsurprisingly, to resolve this we have to think in terms of two levels of abstraction. We must understand how these levels relate to each other, but we must keep them distinct.

At the capability level, Alice is sharing with Bob the specific right to (at the money level) gain an exclusive on 10 fungible units of a particular currency. At the moment when Bob's foo method binds the incoming purse to the payment parameter-variable, Bob is now (capability level) sharing with Alice this specific right. In the next statement, where Bob deposits the money into his own purse, he is exercising this right to gain an exclusive, and thereby obtaining exclusive rights.

To discuss the instruments presented below, we need to exercise similar care in keeping the levels straight.

Options

From the point of view of a buyer, an option is the right to buy or sell some amount of some underlying instrument, such as stock, for a fixed price, within a period of time. From the point of view of the seller (called an option-writer), it is an offer to sell or buy at a locked in price, where the offer expires at a future time. Here we deal only with a covered call option. Call means the option holder may buy the stock. Covered means that the option seller puts aside stock to cover the possible exercise of the option as long as the option is outstanding, ensuring that he has the stock to sell should the option holder exercise her rights to buy.

Due to space limitations, the following is an idealization which nevertheless should present the essence of a covered call option as a smart contract. Assume the existence of a broker mutually trusted by the option buyer and seller. The option seller "writes" the contract by delivering to the broker the last four parameters of the makeCoveredCallOption below. (The first three parameters come from the broker.) The broker invokes a makeCoveredCallOption within a vat he is running (so the mutual trust of the contract-platform can be inherited from mutual trust in the broker), and delivers to the option buyer the resulting coveredCallOption. The option buyer can exercise the option, paying the exercise price and gaining the stock, by calling the exercise method before the deadline has expired.

Among the simplifications:

  • This protocol assumes share ownership is handled using the same code we've been using for money. This seems plausible, as stock ownership is also exclusive, fungible, and assayable. However, it is also exercisable -- by voting and collecting dividends [MacKenzie99]. While stock is put aside to cover a call, the owner loses the right to sell it, but, until the option is exercised, retains the exercise rights of the stock. The following code ignores this issue.

  • We do not show the broker's role in the payment of the premium from the buyer to the writer to pay for the initial purchase of the option. A realistic broker might escrow both the stock from the writer and the premium from the buyer, and only once both are successfully escrowed, then release the premium to the writer and the derived option to the buyer. The code implementing this logic is properly separate from the logic of the option itself.

  • We ignore the broker's fees. A realistic broker may charge the buyer for setting up the option, and charge the writer when the option is exercised.

  • The options normally traded are not covered. Rather, real world brokers absorb some of the risk that the writer may not be able to provide the stock when the buyer exercises. Brokers then partially mitigate these risks via complex contracts with the writers, involving margin calls and such. To understand such complex networks of contracts, we should start by first understanding the much simpler covered contracts we show here.

  • Again due to space limitations, the following code ignores distribution and concurrency issues.

The only abstraction used below that is not yet explained is timer. timer provides access to real-world time. Its relevant operations are:

timer.whenPast(absMillis, thunk)
  This tells the timer to call thunk() after at least absMillis milliseconds have past since the epoch. (A thunk is a no-argument procedure, such as cancel(), defined below.)
timer.now()
  What's the current time?
timer.date(time)
  Returns a readable date string representing time

In a typical object system, such a timer service might be globally accessible, but this would violate the capability constraints. No amount of internal computation would enable an object to determine the time, so access to time gives the object the ability to be affected by the outside world. By making this access into a first class object, we can instead supply other sources of time, as would be required, e.g., for deterministic replay.

An Options Smart Contract

? pragma.syntax("0.8")
# E sample
def makeCoveredCallOption(timer,                # access to a real-world time service
                          escrowedStock,        # reserves stock while offer is OPEN
                          escrowedMoney,        # intermediate money-transfer purse

                          # The 3 args above are from broker. The 4 below  from options-writer

                          stockSrc,             # provides the stock offered for sale
                          deadline :int,        # time until which the offer is OPEN
                          moneyDest,            # where the seller receives payment
                          strikePrice :int      # price demanded  per share of stock
) :any {
    def numShares :int := stockSrc.getBalance() # how many shares are offered
    escrowedStock.deposit(numShares, stockSrc)  # escrow all the shares in stockSrc

    var state := "OPEN" # one of OPEN, CLOSED, or CANCELLED

    def cancel() :void {
        if (state == "OPEN") {
            stockSrc.deposit(numShares, escrowedStock) # return stock to seller
            state := "CANCELLED"
        }
    }
    timer.whenPast(deadline, cancel) # after deadline, call cancel()

    def coveredCallOption {
        to __printOn(out) :void {
            if (state == "OPEN") {
                # converts to readable date string
                def expiration := timer.date(deadline)
                out.print(`<option to buy $numShares ` +
                          `for $strikePrice per share by $expiration>`)
            } else {
                out.print(`<$state OPTION>`)
            }
        }
        to getState()       :any { return state }
        to getNumShares()   :any { return numShares }
        to getStrikePrice() :any { return strikePrice }
        to getDeadline()    :any { return deadline }

        to exercise(moneySrc, stockDest) :void {
            # if not OPEN, throw "not open"
            require(state == "OPEN", thunk{"not open"})
            require(timer.now() < deadline, thunk{"too late"})

            def exerciseCost := strikePrice * numShares
            escrowedMoney.deposit(exerciseCost, moneySrc)
            # only if the call-writer can be  properly paid do we proceed
            state := "CLOSED"
            try {
                moneyDest.deposit(exerciseCost, escrowedMoney)
            } finally {
                stockDest.deposit(numShares, escrowedStock)
            }
        }
    }
    return coveredCallOption
}

When the option is written, the stock in the purse provided by the option seller is put into escrow within the returned coveredCallOption, but the original purse is remembered in case the stock needs to be returned. The coveredCallOption and the cancel function share the same state. They can be seen as facets of the option-composite. Only the timer holds a reference to the cancel facet.

If the option holder calls exercise, then the option will first attempt to deposit from the holder's moneySrc purse into the broker's empty escrowedMoney purse. Only if this succeeds does the option then transfer the money and stock from the purses in which they are escrowed into the writer's moneyDest purse and the holder's stockDest purse, respectively, and close the option. If the money is not successfully escrowed, the stock isn't transferred and the option remains open.

Alternatively, if the deadline passes before the option is exercised, the escrowed stock is transferred back into the purse it came from and the option is cancelled.


A qualification that may safely be skipped on a first reading:

After this paper was published, Darius Bacon (darius-at-accesscom.com) rightly observed

This code has a vulnerability not mentioned here, I think. The options-writer could supply an evil [moneyDest] purse that accepts the money and then goes into a loop, preventing (or delaying) the buyer from getting the stock. This is possible because we only ever call the deposit method (and no other) on moneyDest, so moneyDest doesn't have to be a real purse to work -- it can be a wrapper around a real purse. If I'm not mistaken about this, it deserves at least a footnote, so picky bastards like me will know you have some answers.

Well Darius, you provided the footnote. Above we say "due to space limitations, the following code ignores distribution and concurrency issues." Darius has indeed identified one of these concurrency issues. Although in other matters E has object granularity security, in matters of resource allocation E has at best vat granularity security. Among the objects within a vat, all resources are treated as a commons, enabling any to engage in a resource exhaustion attack as a form of denial of service attack, effective against other objects in the same vat. The simplest of these is the one Darius points out: There is no preemptive scheduling within a vat. If an object within the vat goes into an infinite loop, (in the absence of possible mechanisms like watchdog timers, which are not currently part of E, and will never be part of E's default configuration) then no other objects in that vat may ever again get to run again.

However, in a realistic situation, for these very reasons, the moneyDest purse would be operating on the option writer's vat, or a least a vat other than the broker's vat. In this case, the above code would have to invoke the moneyDest purse with the eventual-send operator ("<-"), which does not block the sending vat, but does provide the sending vat information about whether the operation succeeded. To deal with these issues in a partition tolerant fashion in fact requires a more complex protocol, such as the varieties of ERTP. A description of the eventual-send operator is well beyond the scope of this paper.


So what kind of a right have we created here? It is specific, but fungible options can be created. It isn't quite assayable, as the options holder cannot reliably tell which stock is being offered or which currency is demanded in exchange, but a more complex contract in the spirit of the above code can provide full assayability (given trust in the broker, of course). It is certainly exercisable! It also introduces a new dimension -- it is perishable rather than durable. The right to exercise spoils after a time.

However, unlike a real-world option, it is sharable rather than exclusive. If Alice, the initial options holder, wishes to give Bob the option, Bob must assume that Alice still holds it, and therefor may still exercise it. As with the purse, they are sharing rights to manipulate exclusive rights. However, Bob cannot cope in the same manner, since the exclusive he wants now is not an exclusive on the underlying stock but an exclusive on the right to exercise the option. How can we make an exclusive option?

We could try rewriting the above code to provide exclusivity as well, but the result would mix separate concerns into one abstraction. Better to add exclusivity to the above code by composition. Here's an adaptation of our money code to provide exclusivity for a single specific exercisable object:

# E sample
def makeBrandPair := <import:org.erights.e.elib.sealing.makeBrand>

def makeTitleCompany(precious, name) :any {
    require(precious != null, thunk{"must provide an object"})
    def [sealer, unsealer] := makeBrandPair(name)
    def makePurse(var myPrecious) :any {
        def extract() :any {
            require(myPrecious != null, thunk{"empty"})
            def result := myPrecious
            myPrecious := null
            return result
        }
        def purse {
            to __printOn(out) :void { out.print(`<holds $myPrecious>`) }
            to isFull()        :any { return myPrecious != null }
            to sprout()        :any { return makePurse(null) }
            to getExtract()    :any { return sealer.seal(extract) }
            to deposit(src)   :void {
                require(myPrecious == null, thunk{"full"})
                myPrecious := unsealer.unseal(src.getExtract())()
            }
            to exercise(verb, args) :any {
                return E.call(myPrecious, verb, args)
            }
        }
        return purse
    }
    return makePurse(precious)
}

(The E.call method enables one to dynamically (ie, reflectively) call any method of any object. For example, "E.call(bob, "foo", [carol])" has the same effect as "bob.foo(carol)", but the E.call form allows computed verb-names and argument lists.)

Given a single object, makeTitleCompany returns an initial purse holding this object. This purse is able to sprout other empty purses all able to hold only this object. Among such sibling purses, only one holds the object at a time. To move the object from one purse to another, one must have both purses.

Such a purse is also an exercisable right. The holder of a purse may invoke any method on the underlying object. Care must be taken when programming objects that are intended to be held in such purses -- they should be designed not to return references to themselves as the result of any operation, as this would invalidate the exclusivity property.

Once the broker creates the option, using the arguments from the option seller, it wouldn't release this non-exclusive options object to the first buyer, because the first buyer would then be unable to resell it. Instead, it would call makeTitleCompany(option, ...) and give the first buyer, Alice, the resulting purse. It would also hold on to this purse, indexed by a description of the option it created.

When Bob wants to buy an exclusive on the option from Alice, Bob would first go to the broker to acquire an empty purse for holding the option that meets his description. The broker looks up the original purse from the description, and gives Bob a new sprout of this purse. When Alice gives Bob her option-holding purse, he deposits it into the purse he got from the broker. If this succeeds, he knows he now has an exclusive on the option to gain an exclusive on some amount of stock.

Composable Security, Readable Contracts

The kind of composition of abstractions demonstrated above is familiar in the object programming world, but without the security shown. The creation of cryptographic protocols for securely trading a variety of financial instruments is familiar in the financial cryptography world, but without the separation of concerns and easy composability shown. The best capability operating system work [Hardy85] does combine abstraction and security in this way, but without a notation to make the issues clear, and only when all parties fully trust one common platform.

By using the Granovetter Operator as a bridge, we are able to apply strengths from all three worlds synergistically to the engineering of a single integrated system.

Financial cryptography is a broad field encompassing a wide range of more specialized problem areas: cryptosystems, transactional protocols, user interface design, interface with existing financial and legal institutions, accounting, interface with legacy systems, creation of innovative financial instruments and institutions, the list is endless. However, the benefits achievable from specialization in any of these subfields have been limited by the costs of systems integration. It has hitherto been difficult to layer abstractions so that one can think clearly about one part of a system design without having to think about all the other parts of the system design simultaneously. This is especially troublesome in the development of financial systems where developers must proceed very cautiously due to the enormous potential cost of errors. It is our hope that the abstractions, tools and notation we have presented here will go a long way towards filling the need for the kinds of compositional power that will enable us to realize the tremendous promise of the world of electronic commerce.

 
Unless stated otherwise, all text on this page which is either unattributed or by Mark S. Miller is hereby placed in the public domain.
ERights Home elib / capability / ode 
Back to: As Game On to: Acknowledgements
Download    FAQ    API    Mail Archive    Donate

report bug (including invalid html)

Golden Key Campaign Blue Ribbon Campaign