Skip to content

Conversation

@shrugs
Copy link
Contributor

@shrugs shrugs commented Jun 17, 2018

🚀 Description

/**
 * @title NonceTracker
 * @author Matt Condon (@shrugs)
 * @dev A simple way to keep track of nonces and restrict access.
 * Use the `withAccess` modifier to restrict access by address.
 * Use the `withMaxAccess` modifier to restrict access by address up to a max amount
 * For example, withMaxAccess(msg.sender, 1) will only allow once-per-address.
 * You can also accept nonces from users (as part of a hash you verify).
 */

@shrugs shrugs mentioned this pull request Jun 17, 2018
4 tasks
@frangio frangio self-requested a review July 10, 2018 03:25
@shrugs
Copy link
Contributor Author

shrugs commented Jul 18, 2018

I want to refactor this to use the AutoIncrementing library. Depends on #1023

@shrugs
Copy link
Contributor Author

shrugs commented Jul 25, 2018

Actually, after trying to refactor, I'm not convinced it benefits from using AutoIncrementing at all. @frangio I see you gave a 👍 ; any thoughts?


/**
* @dev call this function when accepting a nonce
* @dev throws if nonce is not strictly greater than previous nonce
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Technically, it reverts 😛

import "../access/NonceTracker.sol";


contract NonceTrackerImpl is NonceTracker {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this be called NonceTrackerMock, for consistency with the rest of the directory?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the pattern I've been using for mock/impl is mock == use a fully-functional implementation, but make it more accessible for testing. implementation == implement some other thing in a way that a real contract would.

but we haven't really followed that at all afaik, so ¯\_(ツ)_/¯

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Haha I see. I'll take a look at making them consistent in the near future then.

contract NonceTracker {
mapping(address => uint256) private nonces;

modifier withAccess(address _address, uint256 _nonce)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the _nonce value supposed to be here? I'm not really sure what the intended usage of this modifier is (there are no docs for it btw).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will add docs :)

But it's intended to "register" your usage of some resource, given a specific nonce. For example, using Bouncer, you would pass a custom nonce to avoid replay attacks and invalidate previous signatures. NonceTracker keeps track of the latest nonces and enforces that they only increase

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh I get it now. A bit convoluted though, isn't it? Since you're free to pass any nonce you wish, I don't really see a use for this other than the Bouncer. It's also wildly different from withMaxAccess (and incompatible, using one in a contract will break the other), to the point where I'm not sure if it shouldn't be its own thing (a Bouncer extension to prevent replaying txs).

@@ -0,0 +1,67 @@

import assertRevert from '../helpers/assertRevert';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We're using require as of #1074 :)


contract('NonceTracker', ([_, owner, anyone, another]) => {
context('canDoThisOnce', function () {
before(async function () {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see what you're doing here with the test cases following a sequence to prevent code duplication, but I'd rather them be a bit longer and independent - fragile test suites are always a PITA.

@nventuro nventuro self-assigned this Jul 28, 2018
@nventuro
Copy link
Contributor

I take it you intended to use AutoIncrementing for WithMaxAccess? What didn't you like about that approach?

@shrugs
Copy link
Contributor Author

shrugs commented Jul 29, 2018

Mostly because AutoIncrementing doesn't (shouldn't?) support manually setting the previous id. It's designed for incrementing ids of things, not tracking nonces. So to support nonce tracking it'd have to have a setter for manually setting the prevId field and now we're sort of breaking minimum concerns.

@nventuro nventuro added feature New contracts, functions, or helpers. contracts Smart contract code. labels Jul 30, 2018
@nventuro
Copy link
Contributor

Agreed, but it'd work if we restricted this to us the withMaxAccess modifier, right? Though at that point I'd call this by some other name, since it's not really doing nonce tracking but call amount restriction.

@shrugs
Copy link
Contributor Author

shrugs commented Aug 2, 2018

I think it's necessary to allow arbitrary nonce submissions, since incrementing won't always be done on-chain (like when using the bouncer pattern; I want to be able to invalidate previous nonces by signing a new nonce and submitting that on-chain).

@shrugs
Copy link
Contributor Author

shrugs commented Sep 4, 2018

closing as part of #1272

@shrugs shrugs closed this Sep 4, 2018
@shrugs shrugs deleted the feat/noncetracker branch September 4, 2018 20:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

contracts Smart contract code. feature New contracts, functions, or helpers.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants