Halborn Logo

// Blog

Blockchain Security

What Is a Timelock Contract?


profile

Rob Behnke

November 29th, 2022


Given the immutability of public blockchains, it is important that transactions are executed only if conditions for safety are satisfied. An example of a safety condition enforced by smart contracts is the timing of certain transactions. 

For example, an auction contract might require users to place bids only within a specific window. Similarly, an Initial Coin Offering (ICO) may prevent investors from transferring newly-acquired tokens until the initial sale is over (to avoid crashes in market value of the token). 

In both cases, a “timelock” is used to restrict access to smart contract functions until a predetermined delay period elapses. In this article, we’ll explore timelock contracts in detail: how they work, why they matter, and how to use them.

What are timelock contracts? 

A timelock is a mechanism for delaying the execution of functions in a smart contract. Timelock contracts implement modifiers that alter the behavior of functions such that those functions cannot be called until a specified time. These modifiers can take the form of a simple “if…else” statements appended to functions (as seen below):

S

modifier onlyBefore(uint time) {

        if (block.timestamp >= time) revert TooLate(time);

        _;

    }

    modifier onlyAfter(uint time) {

        if (block.timestamp <= time) revert TooEarly(time);

        _;

    }

The timelock described above is used in an auction contract to prevent bidders from bidding too early or too late. Here, the function modifiers reference a particular time (represented as a Unix timestamp or period in seconds). If a transaction involves time-triggered functions, the smart contract checks that it occurred within the valid time window (i.e., by using the current block timestamp as a reference). 

The timelock described above is a simple variant, but more complex types exist. Timelocks used in the administration of smart contracts, for example, allow users to “queue” a function call and execute it at a later time (after the delay period passes). 

Timelocks with schedule-and-execute functionality are useful since they allow administrative operations to be executed asynchronously. Some projects use this type of timelock—which we describe below—to manage on-chain governance:

1. The timelock contract is set as the administrator of one or more smart contracts that control a protocol’s operations. Thus, administrative functions (e.g., minting tokens or changing fee parameters) can only be called by the timelock smart contract. 

2. “Proposers” schedule maintenance operations by calling the timelock contract and passing the address of the target contract and other necessary data as function arguments. Meanwhile, “executors” trigger the timelock contract to call the target smart contract once the queued operations have undergone the delay period. 

The benefit of this timelock variant is that the proposer and executor roles can be split among different individuals to ensure decentralization and efficiency. Of course, the objective of delaying operations remains—function calls cannot be executed unless they have been queued in advance. 

Benefits of using timelock contracts

Improve governance

Many blockchain protocols use an on-chain governance system to manage changes to business logic in smart contracts. Typically, such changes must be approved in an on-chain vote by token holders before trusted parties can initiate the upgrade. 

While ideal, on-chain governance can be risky–an attacker might flash-loan tokens and force through a malicious proposal, or a founder can abuse privileges and implement changes without consulting users. To mitigate these risks, projects like Uniswap and Compound use timelocks to impose delays on the execution of administrative operations in protocol contracts. 

In such cases, proposals to modify protocol parameters must pass through the timelock which imposes a hardcoded minimum delay on execution (typically two days). This ensures community members have adequate notice of planned operations and plan a response (such as pushing for the cancellation of a proposal or exiting the system). 

Satisfy business requirements

As explained previously, a timelock smart contract could be necessary for the proper functioning of a blockchain application. On-chain auctions, ICOs, and NFT mints are examples of use cases that may require time-locking contract functions. DeFi applications can also benefit from using timelocks as explained below:

Suppose a borrowing platform relies on an on-chain price oracle to value user-provided collateral and determine how much a user can borrow from the system. It is possible for an attacker to artificially inflate the valuation of assets deposited as collateral via price oracle manipulation

A suggestion to prevent this type of attack is to impose a minimum delay on users entering and exiting the system. Since a would-be attacker needs to perform two trades—one to manipulate asset prices and another to borrow at the inflated price—in the same transaction, setting a delay (e.g., one block) between deposits and borrows can reduce the risk of price oracle manipulation. 

What are the downsides to using a timelock?

Risk of malicious actions

Although useful from a security perspective, timelock smart contracts may fail to provide adequate security if implemented incorrectly. Examples of attack vectors to consider when using timelocks include:

  • Insufficient delay: The security value of a timelock depends on the preset delay period. A low minimum delay threshold means malicious proposals may proceed before they can be detected. For instance, the Beanstalk protocol imposed a one-day delay on proposal execution—but that was apparently not enough for the community to notice the malicious proposal in time.    
  • Privileged access: The account that deployed the timelock contract on the blockchain may retain administrative control of the contract. In this case, a malicious party can abuse that trust to modify the delay for selfish reasons (e.g., reducing the delay in performing sensitive actions or delaying user actions like performing withdrawals).
  • Timestamp dependency vulnerabilities: Relying on block timestamps for smart contract execution can result in timestamp dependence. Block producers control timestamp values (the only rule is that the timestamp for a new block must be strictly greater than the previous block) and can possibly set a block’s timestamp far into the future to simulate the passage of time. 

We outline some measures for solving the problem in our previous article on timestamp dependency vulnerabilities. For example, you may consider using block height to measure time instead of using block.timestamp. 

Decreases efficiency 

Using a timelock to control maintenance operations in a smart contract can decrease efficiency for developers. For example, timelocks reduce the ability to quickly implement emergency responses, like pausing a smart contract in response to an exploit. 

Delaying certain user operations can also impact an application’s UX. If a protocol delays withdrawals of tokens locked in a project, users might be wary of using it in the future–since it promotes capital inefficiency and results in poorer liquidity. Similarly, imposing delays on entries and exits (to prevent oracle manipulation) can break atomic composability and reduce utility for traders. 

Conclusion 

Timelocks can be a useful addition to your smart contract security toolbox. As seen in the various examples highlighted in the article, timelocks—if used properly—provide a form of “defense-in-depth” by adding extra security measures in smart contracts. 

That said, blockchain developers need to balance speed and security when using timelocks. This might require, say, experimenting with different values for the delay threshold before finding an optimal option. Another strategy is to make it possible for trusted parties to bypass the timelock in case of an emergency (although this power should be adequately decentralized and subject to checks). 

Lastly, it is ideal to ensure a timelock contract is free from centralized control. One way to do this is for the contract deployer to renounce ownership of the timelock contract. Thus, any changes to the timelock’s operation (e.g., changing the minimum/maximum delay) will need to go through the timelock process.