Skip to content
This repository has been archived by the owner on Mar 28, 2023. It is now read-only.

Two-step change for governable values #515

Merged
merged 17 commits into from
Mar 16, 2020
Merged

Two-step change for governable values #515

merged 17 commits into from
Mar 16, 2020

Conversation

NicholasDotSol
Copy link
Contributor

@NicholasDotSol NicholasDotSol commented Mar 5, 2020

closes: #493

Changing/upgrading things in the System contract without warning can lead to unpredictable function call behavior.

Make all upgrades require two steps with a mandatory time window between them. The first step merely broadcasts to users that a particular change is coming, and the second step commits that change after a suitable waiting period.

  • Governance Time delay 1 hour, set arbitrarily.
  • Currently, the initial update functions are unlocked. This means that if a change is incoming and is halfway through the waiting period, the initial update function can be called again, the timer resets, an event is fired and the new change is now pending.

NicholasDotSol added 2 commits March 5, 2020 09:24
The time delay ensures that users have more information regarding the
state of the contract.
This is to avoid situatoins where the state of a Deposit is
unpredictable due to governance changes earlier within the same block.
/// @notice Set the system signer fee divisor.
/// @dev This can be finalized by callingm `finalizeSignerFeeDivisorUpdate`
Copy link
Member

Choose a reason for hiding this comment

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

callingm -> calling

Comment on lines 229 to 232
require(
block.timestamp.sub(signerFeeDivisorChangeInitiated) >= governanceTimeDelay,
"Timer not elapsed, or change not initiated"
);
Copy link
Member

Choose a reason for hiding this comment

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

Could we extract this common part from finalize* functions to a modifier?
E.g.:

    function finalizeSignerFeeDivisorUpdate()
        external
        onlyOwner
        afterChangeDelay(signerFeeDivisorChangeInitiated)
    {
        signerFeeDivisor = newSignerFeeDivisor;
        emit SignerFeeDivisorUpdated(newSignerFeeDivisor);
        newSignerFeeDivisor = 0;
        signerFeeDivisorChangeInitiated = 0;
    }

    modifier afterChangeDelay(uint256 _changeInitializedTimestamp) {
        require(
            block.timestamp.sub(_changeInitializedTimestamp) >=
                governanceTimeDelay,
            "Timer not elapsed, or change not initiated"
        );
        _;
    }

Of course needs replacing afterChangeDelay with some clever name.

Comment on lines +235 to +244
newSignerFeeDivisor = 0;
signerFeeDivisorChangeInitiated = 0;
Copy link
Member

Choose a reason for hiding this comment

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

What will happen if we call finalizeSignerFeeDivisorUpdate once again? Will signerFeeDivisor be set to 0?

Maybe we shouldn't do newSignerFeeDivisor = 0 here?
Or maybe we should check if signerFeeDivisorChangeInitiated > 0 at the beginning?

require(
  _changeInitializedTimestamp > 0,
  "Change not initiated"
);

require(
  block.timestamp.sub(_changeInitializedTimestamp) >= governanceTimeDelay,
  "Timer not elapsed"
);

Copy link
Member

Choose a reason for hiding this comment

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

Comment above refers also to other functions.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yes, this we need

Copy link
Member

Choose a reason for hiding this comment

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

@NicholasDotSol have you pushed any updates around that?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yep, we have 2 separate requirements in onlyAfterDelay modifier now

Comment on lines 313 to 318
require(collateralizationThresholdsChangeInitiated > 0, "Update not initiated");

uint256 elapsed = block.timestamp.sub(collateralizationThresholdsChangeInitiated);
return (elapsed >= governanceTimeDelay)?
0:
governanceTimeDelay.sub(elapsed);
Copy link
Member

Choose a reason for hiding this comment

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

Can we extract common code to an internal function?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

sure, i'm ok with that because this isn't a user-facing function so the slightly extra cost doesn't matter much. also deployment should be cheaper

describe("setSignerFeeDivisor", async () => {
it("sets the signer fee", async () => {
await tbtcSystem.setSignerFeeDivisor(new BN("201"))
describe("update Signer fee", async () => {
Copy link
Member

Choose a reason for hiding this comment

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

update Signer fee -> update signer fee?

implementation/test/TBTCSystemTest.js Show resolved Hide resolved
implementation/test/TBTCSystemTest.js Show resolved Hide resolved
implementation/test/TBTCSystemTest.js Show resolved Hide resolved
implementation/test/TBTCSystemTest.js Show resolved Hide resolved
NicholasDotSol added 3 commits March 6, 2020 09:18
Uninitiated change and unelapsed timer are separate test cases now.
Ensure the values are changes correctly
NicholasDotSol added 2 commits March 6, 2020 11:29
getRemainingUpdateTime functions share most of their functinality.
Extract that functionality into an internal function.
NicholasDotSol and others added 8 commits March 6, 2020 11:30
Ensure the update overrides the old value and resets the timestamp.
Time tests have a grac eperiod of 1 second to account for
unexpected time incrememnts due due to computation time.
From 1 hour to 6
Adding the timestamp grace
allows the test to be off by 1
due to execution time pushing the timestamp up by 1 unpredictably
@Shadowfiend Shadowfiend merged commit fbb2018 into master Mar 16, 2020
@Shadowfiend Shadowfiend deleted the two-step-gov branch March 16, 2020 19:27
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Waiting period for system changes
3 participants