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
This commit is contained in:
@@ -0,0 +1,101 @@
|
||||
# Review package: a6f9533aacd4d6cdbbf9682bfd8482ced065ebf5..1f4175ba729fbbab58538cd3ac02b5459e014c86
|
||||
|
||||
## Commits
|
||||
1f4175b feat: add valueless mock USDC
|
||||
|
||||
## Files changed
|
||||
src/MockUSDC.sol | 18 ++++++++++++++++
|
||||
test/MockUSDC.t.sol | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
2 files changed, 78 insertions(+)
|
||||
|
||||
## Diff
|
||||
diff --git a/src/MockUSDC.sol b/src/MockUSDC.sol
|
||||
new file mode 100644
|
||||
index 0000000..96ca297
|
||||
--- /dev/null
|
||||
+++ b/src/MockUSDC.sol
|
||||
@@ -0,0 +1,18 @@
|
||||
+// SPDX-License-Identifier: MIT
|
||||
+pragma solidity 0.8.35;
|
||||
+
|
||||
+import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
|
||||
+import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
|
||||
+
|
||||
+/// @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);
|
||||
+ }
|
||||
+}
|
||||
diff --git a/test/MockUSDC.t.sol b/test/MockUSDC.t.sol
|
||||
new file mode 100644
|
||||
index 0000000..028c1a0
|
||||
--- /dev/null
|
||||
+++ b/test/MockUSDC.t.sol
|
||||
@@ -0,0 +1,60 @@
|
||||
+// SPDX-License-Identifier: MIT
|
||||
+pragma solidity 0.8.35;
|
||||
+
|
||||
+import {Test} from "forge-std/Test.sol";
|
||||
+import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
|
||||
+import {MockUSDC} from "../src/MockUSDC.sol";
|
||||
+
|
||||
+contract MockUSDCTest is Test {
|
||||
+ MockUSDC internal token;
|
||||
+ address internal constant STRANGER = address(0xBEEF);
|
||||
+ address internal constant RECIPIENT = address(0xCAFE);
|
||||
+ address internal constant SPENDER = address(0xD00D);
|
||||
+
|
||||
+ function setUp() public {
|
||||
+ token = new MockUSDC(address(this));
|
||||
+ }
|
||||
+
|
||||
+ function testMetadataUsesSixDecimalMockUSDC() public view {
|
||||
+ assertEq(token.name(), "Mock USD Coin");
|
||||
+ assertEq(token.symbol(), "mUSDC");
|
||||
+ assertEq(token.decimals(), 6);
|
||||
+ }
|
||||
+
|
||||
+ function testInitialSupplyIsZero() public view {
|
||||
+ assertEq(token.totalSupply(), 0);
|
||||
+ }
|
||||
+
|
||||
+ function testMintMintsToRecipientWhenCalledByOwner() public {
|
||||
+ token.mint(RECIPIENT, 1_250_000);
|
||||
+
|
||||
+ assertEq(token.totalSupply(), 1_250_000);
|
||||
+ assertEq(token.balanceOf(RECIPIENT), 1_250_000);
|
||||
+ }
|
||||
+
|
||||
+ function testMintRevertsWhenCalledByNonOwner() public {
|
||||
+ vm.prank(STRANGER);
|
||||
+ vm.expectRevert(abi.encodeWithSelector(Ownable.OwnableUnauthorizedAccount.selector, STRANGER));
|
||||
+ token.mint(RECIPIENT, 1);
|
||||
+ }
|
||||
+
|
||||
+ function testTransferMovesMintedBalance() public {
|
||||
+ token.mint(address(this), 1_250_000);
|
||||
+
|
||||
+ token.transfer(RECIPIENT, 250_000);
|
||||
+
|
||||
+ assertEq(token.balanceOf(address(this)), 1_000_000);
|
||||
+ assertEq(token.balanceOf(RECIPIENT), 250_000);
|
||||
+ }
|
||||
+
|
||||
+ function testApproveSetsAllowanceForSpender() public {
|
||||
+ token.approve(SPENDER, 750_000);
|
||||
+
|
||||
+ assertEq(token.allowance(address(this), SPENDER), 750_000);
|
||||
+ }
|
||||
+
|
||||
+ function testConstructorRevertsForZeroInitialOwner() public {
|
||||
+ vm.expectRevert(abi.encodeWithSelector(Ownable.OwnableInvalidOwner.selector, address(0)));
|
||||
+ new MockUSDC(address(0));
|
||||
+ }
|
||||
+}
|
||||
Reference in New Issue
Block a user