Skip to content
Permalink
Branch: master
Find file Copy path
Find file Copy path
1 contributor

Users who have contributed to this file

92 lines (85 sloc) 3.28 KB
parameter (or (unit %default)
(pair %main
(pair :payload
(nat %counter) # counter, used to prevent replay attacks
(or :action # payload to sign, represents the requested action
(lambda %operation unit (list operation))
(pair %change_keys # change the keys controlling the multisig
(nat %threshold) # new threshold
(list %keys key)))) # new list of keys
(list %sigs (option signature)))); # signatures
storage (pair (nat %stored_counter) (pair (nat %threshold) (list %keys key))) ;
code
{
UNPAIR ;
IF_LEFT
{ # Default entry point: do nothing
# This entry point can be used to send tokens to this contract
DROP ; NIL operation ; PAIR }
{ # Main entry point
# Assert no token was sent:
# to send tokens, the default entry point should be used
PUSH mutez 0 ; AMOUNT ; ASSERT_CMPEQ ;
SWAP ; DUP ; DIP { SWAP } ;
DIP
{
UNPAIR ;
# pair the payload with the current contract address, to ensure signatures
# can't be replayed accross different contracts if a key is reused.
DUP ; SELF ; ADDRESS ; PAIR ;
PACK ; # form the binary payload that we expect to be signed
DIP { UNPAIR @counter ; DIP { SWAP } } ; SWAP
} ;
# Check that the counters match
UNPAIR @stored_counter; DIP { SWAP };
ASSERT_CMPEQ ;
# Compute the number of valid signatures
DIP { SWAP } ; UNPAIR @threshold @keys;
DIP
{
# Running count of valid signatures
PUSH @valid nat 0; SWAP ;
ITER
{
DIP { SWAP } ; SWAP ;
IF_CONS
{
IF_SOME
{ SWAP ;
DIP
{
SWAP ; DIIP { DUUP } ;
# Checks signatures, fails if invalid
{ DUUUP; DIP {CHECK_SIGNATURE}; SWAP; IF {DROP} {FAILWITH} };
PUSH nat 1 ; ADD @valid } }
{ SWAP ; DROP }
}
{
# There were fewer signatures in the list
# than keys. Not all signatures must be present, but
# they should be marked as absent using the option type.
FAIL
} ;
SWAP
}
} ;
# Assert that the threshold is less than or equal to the
# number of valid signatures.
ASSERT_CMPLE ;
# Assert no unchecked signature remains
IF_CONS {FAIL} {} ;
DROP ;
# Increment counter and place in storage
DIP { UNPAIR ; PUSH nat 1 ; ADD @new_counter ; PAIR} ;
# We have now handled the signature verification part,
# produce the operation requested by the signers.
IF_LEFT
{ # Get operation
UNIT ; EXEC
}
{
# Change set of signatures
DIP { CAR } ; SWAP ; PAIR ; NIL operation
};
PAIR }
}
You can’t perform that action at this time.