Atem
Blockchain Engineer
November 2022 – June 2024
Atem was a carbon-credit aggregation platform, integrating tokenised credits on Polygon and Celo, aimed at traditional companies rather than crypto natives. That audience shaped everything: the people buying were not going to tolerate crypto-shaped risk.
Adapters for the tokenisation protocols
Carbon credits had been tokenised by several protocols, each with its own mechanics. I built adapter contracts to buy and retire credits from our application — first for Toucan, the largest, then for C3.
Buying meant automating a swap from USDC into a pool token, then redeeming that pool token for the specific project credit through the protocol's own contracts. Both went to production on Polygon, built in Solidity with a Hardhat and TypeScript test suite running against a forked node, and deployment automated so that verification, logging and monitoring registration happened as one step.
The awkward part was the second adapter, which needed two swaps across two different exchanges — and the second exchange used an architecture substantially unlike the Uniswap-style approach nearly everything else had followed. That was a matter of reading the documentation properly and finding working examples rather than assuming the familiar pattern would transfer.
Subgraphs
Two were needed. One tracked pool reserves so we could calculate live prices for the bundle tokens — adapted from an existing subgraph, brought up to date across several breaking dependency changes, and stripped of the fields we did not need. The other indexed events from our own adapters, giving the backend reliable confirmation of purchases and retirements so inventory and user history stayed correct.
Threat modelling
Because our customers were conventional businesses holding real value in USDC and credits, we did a proper platform-wide threat model rather than a checklist.
We inventoried every component and how they connected — databases, contracts, frontend, hosting, multisigs, oracles, the custody provider, the exchange account. Then we built out the threats systematically, sized each one, and wrote a matching control for every threat covering three things: how we prevent it, how we would detect it, and what we would do if it happened anyway. We shared the model and the contracts with an external security firm for an outside read.
The lesson that stuck: vulnerabilities appear where you are not looking, so thoroughness beats cleverness. Thinking explicitly as an attacker, and writing it all down somewhere structured enough to keep adding to over weeks, was what made it useful.
Migrating custody
We had originally given each customer an individual custodial wallet through a third-party provider, which shaped both the contracts and the backend. When the business concluded that per-customer wallets were unnecessary, I spent several months evaluating alternatives and then specified the migration to OpenZeppelin Defender's relayer, sitting between our backend and our contracts.
The real problem was not technical, it was the trade-off. Everything in a multisig is safest and least usable — every retirement needs multiple signatures. Everything in a hot wallet is usable and a target, increasingly so as the value held grows. We settled on holding a working balance hot, moving anything above a threshold to the multisig, and alerting on the crossing in both directions.
It moved across with no interruption to the service and no risk to customer holdings, on schedule.