Files
uupl-smart-contract/.superpowers/sdd/2026-08-17-uups-bank-demo/task-2-brief.md
T
golemandClaude Opus 5 fa36215def docs: track superpowers working documents in git
The uups-bank-demo wave's SDD records (ledger, six task briefs and reports,
review diffs) and the brainstorm design mockups were git-ignored, so they
existed only on one sandbox VM and reached no remote — this repo had no remote
at all until now.

Removes `.superpowers/` from .gitignore and the `*` .gitignore the superpowers
plugin writes inside .superpowers/sdd/; the second blocks the directory even
with the first removed.

Excluded as ephemeral local-server state, and now ignored by name:
.last-port, .last-token (a 64-char session token for a brainstorm server on a
port that is long gone), and the per-session state/ directories.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Fnwzj6McD6kSkXwjUKFKxe
2026-08-20 14:38:00 -06:00

1.6 KiB
Raw Blame History

Task 2: Build the valueless six-decimal mock asset with TDD

Files:

  • Create: src/MockUSDC.sol
  • Create: test/MockUSDC.t.sol

Interfaces:

  • Produces MockUSDC.mint(address,uint256), decimals() == 6, and standard ERC-20 behavior.

  • Consumed by the bank tests, deployment scripts, and dashboard ABI export.

  • Write test/MockUSDC.t.sol first. Cover the exact name/symbol/decimals, owner-only mint, successful mint, transfer/approve behavior inherited from ERC-20, and zero initial supply. Use vm.expectRevert(abi.encodeWithSelector(Ownable.OwnableUnauthorizedAccount.selector, stranger)) for non-owner minting.

  • Run the focused test and observe red:

forge test --match-path test/MockUSDC.t.sol -vvv --force

Expected red: src/MockUSDC.sol is missing.

  • Implement only the tested contract:
/// @notice Educational mock token with no monetary value. Never use as real USDC.
contract MockUSDC is ERC20, Ownable {
    constructor(address initialOwner) ERC20("Mock USD Coin", "mUSDC") Ownable(initialOwner) {}

    function decimals() public pure override returns (uint8) { return 6; }
    function mint(address to, uint256 amount) external onlyOwner { _mint(to, amount); }
}

Reject a zero initialOwner through OpenZeppelins OwnableInvalidOwner behavior. Do not add faucet, burn, permit, blacklist, proxy, or bank-specific logic.

  • Run red-to-green verification:
forge fmt
forge test --match-path test/MockUSDC.t.sol -vvv --force

Expected: all mock-token tests pass.

  • Commit:
git add src/MockUSDC.sol test/MockUSDC.t.sol
git commit -m "feat: add valueless mock USDC"