Skip to content
THREATWIRE

Defensive pattern

Guarded delegation pattern (illustrative)

Shows the three controls that would have stopped this incident: an authority check on the function, an allow-list for the adapter it may call, and revocation after use. Illustrative, not compiled, not audited.

Code

Written by ThreatWire to illustrate the fix. Not compiled or audited, and not the affected project's code.

Guarded delegation pattern (illustrative)37 lines
1// Illustrative defensive pattern written by ThreatWire. It is NOT the keeper's code and has not
2// been compiled or audited. It shows the shape of the fix described in the incident record.
3
4interface IVat {
5 function hope(address usr) external;
6 function nope(address usr) external;
7}
8
9contract GuardedKeeper {
10 IVat public immutable vat;
11 address public owner;
12 mapping(address => bool) public approvedAdapter;
14 modifier auth() {
15 require(msg.sender == owner, "unauthorized");
16 _;
17 }
19 constructor(IVat _vat) {
20 vat = _vat;
21 owner = msg.sender;
22 }
24 function setAdapter(address adapter, bool ok) external auth {
25 approvedAdapter[adapter] = ok;
26 }
28 // A function that grants rights over this contract's Vat account, or calls back into a
29 // supplied address, is an authority transfer. It needs the same gate as every other
30 // privileged function, an allow-list for the target, and a revocation once the work is done.
31 function runWith(address adapter) external auth {
32 require(approvedAdapter[adapter], "adapter not approved");
33 vat.hope(adapter);
34 // ... perform the intended work with the adapter ...
35 vat.nope(adapter);
36 }

Components and what they do

  • auth modifier
  • approvedAdapter allow-list
  • hope then nope around the callback

Fixes and defensive tests

  • Authority check on every function that grants rights or calls out to a supplied address.
  • Allow-list the counterparties a keeper may delegate to.
  • Revoke delegations in the same call.

Contracts and transactions from the incident

Related files

1 linked

Imports used by this file, other reproduction files from the same month or protocol in the dataset, and patterns for the same incident. Each opens in our reader with verbatim source.

File record

Name
Guarded delegation pattern (illustrative)
Author
ThreatWire editorial
Language
Solidity
Size
37 lines
Date
2026-10-19
Licence
ThreatWire editorial text; all rights reserved
Retrieved
2026-10-19
Incident
MakerDAO flip keeper: an unprotected function handed an attacker control of dormant auction winnings
Protocols
Third-party ETH-A flip keeper
Chains
Ethereum

Provenance

Retrieved 2026-10-19. Original text written by ThreatWire. ThreatWire has never executed this file.