SECRET OF CSS

How to Auto-Pause a Smart Contract | by Stephen Lloyd Webber | Aug, 2022


Working with OpenZeppelin Defender

0*g3kat9CDkyUU qoW
Photo by Ivan Bandura on Unsplash

One of the key capabilities of OpenZeppelin Defender is its usefulness for security monitoring and general automation. This guide makes use of several Defender components to automate incident response for a given set of conditions on an ERC20 contract.

OpenZeppelin Defender has several main functionality components: Sentinel, Autotasks, Admin, and Relayer. Each component serves as an important building block for customizing an automation setup for your dapp or protocol.

In this system design, a Sentinel monitors transactions on the contract, and is set up to automatically fire an Autotask in the event of a large token transfer. The Autotask script sends a pause transaction to the ERC20 contract via a Relayer.

0*uKkpfWITE0sS6YDN

First, sign up for Defender and ensure the EOA used for contract deployment is funded with Goerli ETH (via a faucet).

Fork the Fork the demo repo.

Clone your fork and install dependencies:

$ git clone https://github.com/[GitHub username]/pause-guardian.git
$ cd pause-guardian
$ npm install

Supply the necessary api keys in your local .env file. The following values are expected:

PRIVATE_KEY : For contract deployment on Goerli network

API_KEY : Defender team API key

API_SECRET : Defender team API secret

The OpenZeppelin Contracts Wizard features an API for easy smart contract creation. Generate an ERC20 contract that is Mintable, Pausable, and implements role-based access control, with 1 million tokens pre-minted. The pre-supplied script automates this:

import { erc20 } from '@openzeppelin/wizard'const params = {
name: 'ExampleToken',
symbol: 'ETK',
mintable: true,
premint: '1000000',
access: 'roles',
pausable: true,
}
const contract = erc20.print(params)

Run with $ npm run generate

Next, run $ npm run deploy to compile and deploy the contract.

const adminClient = new AdminClient({
apiKey: process.env.API_KEY,
apiSecret: process.env.API_SECRET,
})
const contractDetails = {
network: 'goerli',
address: contract.address,
name: NAME,
abi: contractABI,
}
const newAdminContract = await adminClient.addContract(contractDetails)

The script makes use of Defender’s admin-client and loads the contract into the Admin dashboard immediately after deployment.

Create a Relayer to run blockchain transactions via API:

$ npm run relay

Now that you have the Relayer, you need to grant it the appropriate role.

The Defender web interface makes it easy to manage access control. Via the Admin dashboard, select the newly-created ERC20 contract, then New Proposal -→ Modify Access. On the next screen, select the PAUSER role from the dropdown and supply the address of the Relayer just created. Select EOA as the execution strategy and select the address of the account used to deploy the contract. Give the access proposal a title and execute it.

0*oTPBceRHnY2s9AQf

Now that you have a Relayer with the appropriate access to pause the contract, it is time to build towards automating this functionality.

Create an Autotask that will send a pause transaction to the deployed ERC20 contract using the Relayer.

$ npm run autotask

The script creates a new Autotask in Defender and uploads the Autotask code, supplying the ID of the Relayer just created to run the transaction using the Relayer.

async function handler(event) {
const provider = new DefenderRelayProvider(event)
const signer = new DefenderRelaySigner(event, provider, { speed: 'fast' })
const erc20 = new ethers.Contract(ADDRESS, ABI, signer) const isPaused = await erc20.paused()
if (!isPaused) {
const tx = await erc20.pause()
console.log(tx)
} else if (isPaused) {
console.log('Contract is paused; doing nothing')
}
}

With the Autotask created, the final building block is to set up a Sentinel to watch for on-chain events and trigger the Autotask.

Sentinels can watch for a wide array of contract conditions and send notifications or fire Autotasks when triggered.

Run $ npm run sentinel to create a Sentinel that triggers the Autotask if a high volume token transfer is detected:

eventConditions: [
{
eventSignature: 'Transfer(address,address,uint256)',
expression: 'value > 200000e18',
},
],

Now that all the building blocks have been laid, the system is ready to be tested. Try transferring an amount of tokens greater than 200000 from the contract to another account. The Sentinel will detect the high volume Transfer event and trigger the Autotask, the Autotask will send the pause transaction via the Relayer, and the ERC20 contract will pause. Attempting any subsequent high-volume transfer would therefore fail.



News Credit

%d bloggers like this: