{"id":19733066,"url":"https://github.com/bhemen/usdc","last_synced_at":"2025-04-30T02:33:14.377Z","repository":{"id":180466359,"uuid":"562168859","full_name":"bhemen/usdc","owner":"bhemen","description":"Tools for scraping data about Circle's USDC stablecoin on Ethereum","archived":false,"fork":false,"pushed_at":"2024-07-31T20:52:27.000Z","size":10308,"stargazers_count":5,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-05T21:51:14.145Z","etag":null,"topics":["blockchain","circle","ethereum","python","stablecoin","usdc"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bhemen.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-11-05T14:19:06.000Z","updated_at":"2025-01-19T12:20:56.000Z","dependencies_parsed_at":null,"dependency_job_id":"f90dbc45-c6ca-48f5-b94e-e8a17879dd43","html_url":"https://github.com/bhemen/usdc","commit_stats":null,"previous_names":["bhemen/usdc"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bhemen%2Fusdc","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bhemen%2Fusdc/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bhemen%2Fusdc/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bhemen%2Fusdc/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bhemen","download_url":"https://codeload.github.com/bhemen/usdc/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251629395,"owners_count":21618160,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["blockchain","circle","ethereum","python","stablecoin","usdc"],"created_at":"2024-11-12T00:29:02.940Z","updated_at":"2025-04-30T02:33:12.668Z","avatar_url":"https://github.com/bhemen.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Python scripts for analyzing USDC on Ethereum\n\n## USDC\n\nUSDC is a fiat-backed stablecoin issued by Circle.  You can read about the off-chain reserves backing USDC at Circle's [transparency](https://www.circle.com/en/usdc#transparency) page.\nCircle currently issues USDC on [15 blockchains](https://www.circle.com/en/multichain-usdc), but this repository focuses on the contracts that control USDC on Ethereum.\nOn Ethereum, USDC is implemented as an ERC-20 contract, but it has significant additional functionality beyond the minimum specified by the [ERC-20 standard](https://ethereum.org/en/developers/docs/standards/tokens/erc-20/).\n\nThis repository is provided to aid in analysis of the on-chain use of USDC.  If you are considering *using* USDC, please read the [terms of service](https://www.circle.com/en/legal/usdc-terms).\n\n## Contract overview\n\nThe USDC contract is deployed at [0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48](https://etherscan.io/address/0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48) on the Ethereum Mainnet.\n\nThe source code for is available at [Centre's github repository](https://github.com/centrehq/centre-tokens).\n\nFollowing [OpenZeppelin standards](https://docs.openzeppelin.com/contracts/2.x/api/ownership#Ownable), the USDC contract is \"ownable\", \nand the owner is [0xFcb19e6a322b27c06842A71e8c725399f049AE3a](https://etherscan.io/address/0xFcb19e6a322b27c06842A71e8c725399f049AE3a).\n\nThe contract is also \"[Pausable](https://docs.openzeppelin.com/contracts/4.x/api/security#Pausable)\", meaning that the owner can pause the contract at will.  In the context of \nUSDC, pausing the contract prevents all [transfers](https://github.com/centrehq/centre-tokens/blob/master/contracts/v1/FiatTokenV1.sol#L275) (including mints and burns).\n\nThe contract is \"[Blacklistable](https://github.com/centrehq/centre-tokens/blob/master/contracts/v1/Blacklistable.sol)\", meaning that special accounts (\"Blacklisters\") can selectively \nfreeze the funds of target users.  Basically, the contract will not process transfers [to](https://github.com/centrehq/centre-tokens/blob/master/contracts/v1/FiatTokenV1.sol#L276) or from \"Blacklisted\" addresses.\nSince mints and burns are special types of transfers, you cannot mint funds to or burn funds from a \"blacklisted\" address.\nUnlike the \"Ownable\" and \"Pausable\" which were standardized by OpenZeppelin and used by a wide variety of contracts, the Blacklistable property was developed by Centre and the code seems to be specific to the USDC \ncontract.  Other fiat-backed stablecoins (e.g. USDT, USDP, BUSD) implement a similar functionality, but with different terminology and code.\n\n## Tools\n\n[get_usdc_configs.py](get_usdc_configs.py) Will scrape all \"configuration\" events from the USDC contract.  Specifically, it scans the Ethereum blockchain for the following events, \nand records them to [data/usdc_configs.csv](data/usdc_configs.csv).\n\n* [Mint](https://github.com/centrehq/centre-tokens/blob/master/contracts/v1/FiatTokenV1.sol#L53)\n* [Burn](https://github.com/centrehq/centre-tokens/blob/master/contracts/v1/FiatTokenV1.sol#L54)\n* [MinterConfigured](https://github.com/centrehq/centre-tokens/blob/master/contracts/v1/FiatTokenV1.sol#L55)\n* [MinterRemoved](https://github.com/centrehq/centre-tokens/blob/master/contracts/v1/FiatTokenV1.sol#L56)\n* [MasterMinterChanged](https://github.com/centrehq/centre-tokens/blob/master/contracts/v1/FiatTokenV1.sol#L57)\n* [Blacklisted](https://github.com/centrehq/centre-tokens/blob/master/contracts/v1/Blacklistable.sol#L37)\n* [UnBlacklisted](https://github.com/centrehq/centre-tokens/blob/master/contracts/v1/Blacklistable.sol#L38)\n* [BlacklisterChanged](https://github.com/centrehq/centre-tokens/blob/master/contracts/v1/Blacklistable.sol#L39)\n\nThe file [analysis/usdc_analysis.py](analysis/usdc_analysis.py) does some basic analytics, e.g. counting the number of mints and burns by minter address.\n\n## Who's in charge?\n\nUSDC is a proxy contract, meaning that the contract functionality can be changed at any time by the \"owner\"\n\nUSDC is also pausable, meaning that it can be paused at any time by the \"owner\" [0xFcb19e6a322b27c06842A71e8c725399f049AE3a](https://etherscan.io/address/0xFcb19e6a322b27c06842A71e8c725399f049AE3a).  When the contract is paused, no USDC can be minted, burned, frozen or transferred until the owner unpauses the contract.\n\n### Minting\n\nAs of block [15590765](https://etherscan.io/block/15590765), only three addresses have minted USDC. \n1. [0x5B6122C109B78C6755486966148C1D70a50A47D7](https://etherscan.io/address/0x5B6122C109B78C6755486966148C1D70a50A47D7)\n2. [0x19a932fC5A8320939c3575302a8705147a7f27D8](https://etherscan.io/address/0x19a932fC5A8320939c3575302a8705147a7f27D8)\n3. [0x24BDd8771b08C2EA6FE0e898126e65BD49021BE3](https://etherscan.io/address/0x24BDd8771b08C2EA6FE0e898126e65BD49021BE3)\n\nThe vast majority has been minted by address 1 (0x5B...).  Address 2 (0x19...) has minted less than 10,000 USDC, and address 3 (0x24..) seems to have been a test address, \nit only minted 200 USDC, and has been inactive since April 10th 2020.\n\nAll three addresses are Externally Owned Accounts (EOAs)\n\nUSDC has been minted **to** 6 different addresses\n\n1. [0x55FE002aefF02F77364de339a1292923A15844B8](https://etherscan.io/address/0x55FE002aefF02F77364de339a1292923A15844B8)\n2. [0xfFADDD32C3670E429884482aFDF9dFB8aff6Ca43](https://etherscan.io/address/0xfFADDD32C3670E429884482aFDF9dFB8aff6Ca43)\n3. [0x895F07957B863f4AB6086035a6990d8366Bc3266](https://etherscan.io/address/0x895F07957B863f4AB6086035a6990d8366Bc3266)\n4. [0x413a5a3d9451Ac6cAACB759C3514943500156099](https://etherscan.io/address/0x413a5a3d9451Ac6cAACB759C3514943500156099)\n5. [0x28C5B0445d0728bc25f143f8EbA5C5539fAe151A](https://etherscan.io/address/0x28C5B0445d0728bc25f143f8EbA5C5539fAe151A)\n6. [0x87976bDcBe7ec19a1fbD45dc39ce55C00C4790A1](https://etherscan.io/address/0x87976bDcBe7ec19a1fbD45dc39ce55C00C4790A1)\n\nwith the vast majority minted to Address 1 (0x55...).\n\n### Blacklisting\n\nCircle has a brief description of its [\"blacklisting\" policy available on its website](https://www.centre.io/hubfs/PDF/Centre_Blacklisting_Policy_20200512.pdf).\n\nBlacklisting is controlled by [0x5db0115f3b72d19cea34dd697cf412ff86dc7e1b](https://etherscan.io/address/0x5db0115f3b72d19cea34dd697cf412ff86dc7e1b), which is an EOA.  \nThis is the only account to have ever called the \"[blacklist](https://github.com/centrehq/centre-tokens/blob/master/contracts/v1/Blacklistable.sol#L76)\" function.\n\nTo date, [239 accounts have been frozen](https://bloxy.info/txs/events_sc/0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48?signature_id=257159)\n\n## Upgrades\n\nThe USDC contract on Ethereum is a proxy contract, meaning that Circle can change the code at any time they wish.  In fact, Circle has changed the contract several times\n\n### V2 Upgrade (December 2020)\n\n* [Press release](https://www.coinbase.com/blog/usdc-v2-upgrading-a-multi-billion-dollar-erc-20-token)\n* [V2 contract](https://github.com/circlefin/stablecoin-evm/blob/master/contracts/v2/FiatTokenV2.sol)\n\nThe V2 upgrade added the [increaseAllowance](https://github.com/circlefin/stablecoin-evm/blob/master/contracts/v2/FiatTokenV2.sol#L54) and [decreaseAllowance](https://github.com/circlefin/stablecoin-evm/blob/master/contracts/v2/FiatTokenV2.sol#L72) functions.  These functions were introduced to avoid potential attacks where a malicious spender attempted to front-run a user's attempted allowance change (See e.g. [Resolving the Multiple Withdrawal Attack on ERC20 Tokens](https://ieeexplore.ieee.org/document/8802438)).  These functions are not actually part of the ERC-20 standard, and they were actually [*removed* from OpenZeppelin's reference ERC-20 contract](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/4585) before Circle added them to USDC.\n\nThis upgrade also implemented \n* the \"permit\" functionality of [EIP-2612](https://eips.ethereum.org/EIPS/eip-2612)\n* the \"transferwithAuthorization\" of [EIP-3009](https://eips.ethereum.org/EIPS/eip-3009)\n\n### V2.1 Upgrade \n\n* [V2.1 contract](https://github.com/circlefin/stablecoin-evm/blob/master/contracts/v2/FiatTokenV2_1.sol)\n\nThis upgrade was very simple -- it moved all USDC held by the USDC contract itself to a \"lost and found\" address, then [blacklisted the USDC contract itself](https://github.com/circlefin/stablecoin-evm/blob/master/contracts/v2/FiatTokenV2_1.sol#L42) -- preventing users from transferring USDC to the USDC contract.  Confused users frequently transfer their tokens to the token contract itself.  For example, the [USDT contract holds hundreds of thousands of USDC and USDT](https://etherscan.io/address/0xdac17f958d2ee523a2206206994597c13d831ec7).  I assume users transferred USDC to the USDT contract in hopes that this would somehow convert the tokens.  Circle cannot block the USDC contract from holding USDT, however, and so the [USDC contract still holds tens of thousands of dollars worth of USDT](https://etherscan.io/address/0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48), that is effectively frozen in the contract (until Circle makes a future upgrade).\n\n### V2.2 Upgrade (January 2024)\n\n* [Press release](https://www.circle.com/blog/announcing-usdc-v2.2)\n* [V2.2 contract](https://github.com/circlefin/stablecoin-evm/blob/master/contracts/v2/FiatTokenV2_2.sol)\n\nThis upgrade changed the way they implement \"blacklisting\" of addresses in an attempt to save on gas fees.\nIn previous versions of the USDC contract, Circle implemented a \"blacklist\" in the obvious way -- they had a [solidity mapping from address to bool that determined whether you were blacklisted](https://github.com/circlefin/stablecoin-evm/blob/master/contracts/v1/Blacklistable.sol#L29).\n\nIn V2.2 they eliminated this mapping, and stored your \"blacklist\" state [in the top bit of your 256-bit account balance](https://github.com/circlefin/stablecoin-evm/blob/master/contracts/v2/FiatTokenV2_2.sol#L236).\nWhen you try to transfer UDSC to or from an account, the USDC contract needs to lookup the balance of that account anyway, so by storing the \"blacklisted\" bit in the account balance, they save an additional integer lookup.\n\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbhemen%2Fusdc","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbhemen%2Fusdc","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbhemen%2Fusdc/lists"}