Subroutine for security checks (RekeyTo, AssetCloseTo etc)?

Trying to refactor recurrent security checks, like these:

gtxn 1 Fee
int 1000
<=
gtxn 1 AssetCloseTo
global ZeroAddress
==
&&
gtxn 1 RekeyTo
global ZeroAddress
==
&&
...

Ideally I’d like to add these checks as a one liner, to all the transactions. Not being able to figure out how to far - can’t put transactions on the stack / scratch, or pass a variable index to gtxn.

Could be solved using templates but that seems risky.

Actually those tests are really important when using smart signatures (previously called stateless smart contracts).

If you’re only using application / smart contracts (previously called stateful smart contracts), then you most likely don’t need those tests. Indeed, the sender of the transaction in that case is the real user. If the user is willing to pay a very high fee or rekey, it is ok. (It’s a security risk for them, not for your smart contract).

I would also suggest to switch to PyTeal. TEAL is becoming much more complex…

A few other remarks if you’re using smart signatures:

  • do not hardcode 1000 as the minimum fee. This is dangerous if this fee changes. Instead use global MinTxnFee.
  • instead of using a chain of && (which was the only way to do it in the past), use assert:
gtxn 1 Fee
global MinTxnFee
<=
assert

gtxn 1 AssetCloseTo
global ZeroAddress
==
assert

gtxn 1 RekeyTo
global ZeroAddress
==
assert

This is much safer.

1 Like

Thanks! I made the suggested changes and will be migrating everything to PyTeal.

Missed to ask: why do we allow fee < min fee? Probably because it’s not a security issue? Any reason to not assert fee == min fee?

Also, fee <= min fee or fee == min fee would fail if the transaction has a calculated fee (size * fee per byte) and it’s > min fee, how to handle that?

Oh, replying to my first question, I briefly forgot the fee pooling - another transaction in the group could be paying the fee. This explains the <= min fee check.

Which answers my second question probably, all my lsig transactions have a 0 fee because other transaction in the group pays their fee. So I can just check for == 0.

You should be able to do this.

1 Like