The DERC20 token contract implements an ERC20 token with voting, permit, and Ownable features. It includes a vesting mechanism for initial token distribution and a time-based inflation mechanism controlled by the owner. While the contract utilizes standard OpenZeppelin libraries and includes custom error handling, a critical vulnerability was identified where vested tokens are minted to the contract but cannot be released to recipients due to a missing function. Additionally, the pool locking mechanism is non-functional, and significant centralized control by the owner poses economic risks.
On-chain security analysis — is it a scam or legit?
Is gitlawb Safe?
Not verified
This record has not gone through deep verification and is not being monitored. The score is a dated snapshot — the token’s risk can change at any time.Own this token? Put it under verification →The DERC20 token contract implements an ERC20 token with voting, permit, and Ownable features.
Read the full analysis- Ownership not renounced — owner is a contract
- Top-10 concentration > 20%
- Liquidity not locked, but no owner/deployer address holds LP — market-depth risk, not rug risk
- LP top1 unlocked holder = 68.2%
- LP top3 unlocked holders = 91.2%
- 1 Critical finding(s) from audit
- 2 High finding(s) from audit
- 1 Medium finding(s) from audit
- 2 Low finding(s) from audit
Exact factors
- Ownership NOT renounced — owner is a contract (governance/executor, not an EOA)
- Top-10 concentration > 20% (37.2% total → 20.2% effective; 8.8% in EOAs, 28.4% in contracts — mild)
- Liquidity not locked, but no owner/deployer address holds LP — market-depth risk, not rug risk
- LP top1 unlocked holder = 68.2% (independent LP — depth risk, pool = 87% of DEX liquidity)
- LP top3 unlocked holders = 91.2% (independent LP — depth risk, pool = 87% of DEX liquidity)
- 1 Critical finding(s) from audit
- 2 High finding(s) from audit
- 1 Medium finding(s) from audit
- 2 Low finding(s) from audit
Each factor is an on-chain fact recorded at the time of this analysis. The score is computed from them by a deterministic function, so the same contract returns the same score for anyone who runs the audit. How scores are computed
Security Checklist
as of audit · Sep 4Holders
as of audit · Sep 4, 2026- Contractstreasury, vesting, bridge, staking28.4%
- Walletsanonymous holders, free to sell8.8%
- Everyone elsethe rest of the supply62.8%
How holder types affect the score
Share held by contracts — treasury, vesting, bridge or staking — is discounted against share held by wallets when the score is computed: a contract cannot decide to sell the way an anonymous holder can, though it can still be drained or voted to sell. Effective concentration is the figure the risk score is actually calculated from.
Holder balances as recorded by the audit of Sep 4, 2026
Liquidity
as of audit · Sep 4- Uniswap v4WETHAnalysed$527.7K87.5%
- Uniswap v3WETH$47.4K7.8%
- Uniswap v4ETH$8.8K1.5%
- Uniswap v4USDC$6.5K1.1%
- AerodromeUSDC$3.7K0.6%
- Uniswap v3USDC$2.6K0.4%
Show 4 more pairs
The 4 remaining pairs hold $84 between them and are not listed. The risk score reads depth across every pair.
The LP tokens of the analysed pool are not locked or burned, so whoever holds them can withdraw that liquidity.
0xcc94…aab30x080c…00940x6fa8…421e0x58ab…66240xed7a…418d0x13cc…bbd60x40b4…9fd20x5458…25e80xd485…b6930x6313…1a60No privileged address appears among these holders: the unlocked liquidity sits with independent providers, not with the deployer.
Security Findings
CriticalMissing Vesting Release Functionality
The constructor mints vestedTokens to address(this) (the contract itself) for later distribution to recipients based on getVestingDataOf and vestingStart/vestingDuration. However, there is no public function provided in the contract that allows these recipients to claim or release their vested tokens after the vesting period has started or ended. This renders the entire vesting mechanism non-functional, as tokens are locked in the contract indefinitely.C-01
Issue
The constructor mints vestedTokens to address(this) (the contract itself) for later distribution to recipients based on getVestingDataOf and vestingStart/vestingDuration. However, there is no public function provided in the contract that allows these recipients to claim or release their vested tokens after the vesting period has started or ended. This renders the entire vesting mechanism non-functional, as tokens are locked in the contract indefinitely.
Fix
Implement a release or claimVestedTokens function that allows recipients to claim their vested tokens. This function should calculate the amount of tokens eligible for release based on block.timestamp, vestingStart, vestingDuration, totalAmount, and releasedAmount in getVestingDataOf, and then transfer the calculated amount to the recipient. Ensure proper checks to prevent releasing more than totalAmount or before vestingStart.
Status
Unresolved
HighNon-functional Pool Locking Mechanism
The contract includes lockPool and unlockPool functions that set the pool address and toggle the isPoolUnlocked boolean. The stated purpose is to prevent tokens from being transferred into the pool while locked. However, the standard ERC20 _transfer function (inherited from OpenZeppelin) does not check the isPoolUnlocked state or the pool address. Consequently, tokens can still be transferred to the designated pool address even when isPoolUnlocked is false, making the locking mechanism entirely ineffective.H-01
Issue
The contract includes lockPool and unlockPool functions that set the pool address and toggle the isPoolUnlocked boolean. The stated purpose is to prevent tokens from being transferred into the pool while locked. However, the standard ERC20 _transfer function (inherited from OpenZeppelin) does not check the isPoolUnlocked state or the pool address. Consequently, tokens can still be transferred to the designated pool address even when isPoolUnlocked is false, making the locking mechanism entirely ineffective.
Fix
To make the pool locking mechanism functional, override the _transfer function (or a similar internal transfer function) to include a check. If isPoolUnlocked is false, prevent transfers where the to address is the pool address. Alternatively, if this feature is not critical, remove the pool, isPoolUnlocked, lockPool, and unlockPool variables and functions to reduce complexity and potential for misunderstanding.
Status
Unresolved
HighCentralized Control by Owner
The owner of the contract, as defined by the Ownable pattern, has extensive control over critical token parameters and supply. The owner can call mintInflation() to mint new tokens to themselves, burn() tokens from their own address, lockPool()/unlockPool(), and updateMintRate() to change the yearly inflation rate. This high degree of centralization introduces significant governance and economic risks, as a compromised owner key or a malicious owner could manipulate the token supply and value without community consensus.H-02
Issue
The owner of the contract, as defined by the Ownable pattern, has extensive control over critical token parameters and supply. The owner can call mintInflation() to mint new tokens to themselves, burn() tokens from their own address, lockPool()/unlockPool(), and updateMintRate() to change the yearly inflation rate. This high degree of centralization introduces significant governance and economic risks, as a compromised owner key or a malicious owner could manipulate the token supply and value without community consensus.
Fix
Consider implementing a multi-signature wallet for the owner role to distribute control and require multiple approvals for critical operations. For updateMintRate, consider adding a time-lock mechanism or a governance vote to allow the community to react to proposed changes. For mintInflation, consider making it callable by a neutral, audited contract or a DAO, rather than directly by the owner.
Status
Unresolved
MediumPrecision Loss in Inflation Calculation
The mintInflation function calculates yearMint and partialYearMint using integer division: (supply * yearlyMintRate_ * time) / (1 ether * 365 days). While yearlyMintRate_ is expressed in WAD (1 ether = 10^18), integer division inherently truncates decimal parts. For very small supply values, very low yearlyMintRate_, or short time periods, this could lead to a minor loss of precision in the minted amount, potentially resulting in slightly less inflation than mathematically precise calculations would yield.M-01
Issue
The mintInflation function calculates yearMint and partialYearMint using integer division: (supply * yearlyMintRate_ * time) / (1 ether * 365 days). While yearlyMintRate_ is expressed in WAD (1 ether = 10^18), integer division inherently truncates decimal parts. For very small supply values, very low yearlyMintRate_, or short time periods, this could lead to a minor loss of precision in the minted amount, potentially resulting in slightly less inflation than mathematically precise calculations would yield.
Fix
While often acceptable for inflation mechanisms, if high precision is paramount, consider using a fixed-point math library or adjusting the calculation order to minimize truncation effects. For example, ensure the numerator is as large as possible before the final division. However, given the yearly nature of the rate, the current approach is likely sufficient for practical purposes, but the minor precision loss should be acknowledged.
Status
Unresolved
LowConfusing MaxTotalVestedExceeded Requirement
In the constructor, the require(vestedTokens < initialSupply, MaxTotalVestedExceeded(...)); check enforces that the total amount of tokens designated for vesting (vestedTokens) must be strictly less than the initialSupply. This means it's impossible to vest the entire initialSupply, as at least one token must always go to the recipient specified in the constructor. The error message MaxTotalVestedExceeded implies exceeding a maximum, but the condition prevents vestedTokens from even reaching initialSupply, which might be an unintended restriction or confusing given the error name.L-01
MaxTotalVestedExceeded RequirementIssue
In the constructor, the require(vestedTokens < initialSupply, MaxTotalVestedExceeded(...)); check enforces that the total amount of tokens designated for vesting (vestedTokens) must be strictly less than the initialSupply. This means it's impossible to vest the entire initialSupply, as at least one token must always go to the recipient specified in the constructor. The error message MaxTotalVestedExceeded implies exceeding a maximum, but the condition prevents vestedTokens from even reaching initialSupply, which might be an unintended restriction or confusing given the error name.
Fix
Clarify the design intent. If it is acceptable for vestedTokens to equal initialSupply (meaning all initial tokens are vested), change the condition to vestedTokens <= initialSupply. If the current strict inequality is intentional, consider renaming the error or adding a comment to explain why vestedTokens must always be less than initialSupply.
Status
Unresolved
LowHardcoded PERMIT_2 Address
The PERMIT_2 contract address (0x0000…8BA3) is hardcoded as a constant. While this is a standard and widely used address for Permit2, hardcoding it means that if the canonical Permit2 contract were to change in the future (e.g., due to an upgrade or a critical bug requiring a new deployment), this contract would not be able to interact with the new address without a redeployment.L-02
PERMIT_2 AddressIssue
The PERMIT_2 contract address () is hardcoded as a constant. While this is a standard and widely used address for Permit2, hardcoding it means that if the canonical Permit2 contract were to change in the future (e.g., due to an upgrade or a critical bug requiring a new deployment), this contract would not be able to interact with the new address without a redeployment.
Fix
Consider making the PERMIT_2 address configurable by the owner or through a governance mechanism. This would allow for flexibility in case the canonical Permit2 address needs to be updated in the future. For non-upgradeable contracts, this might be less critical, but it's a good practice for long-lived protocols.
Status
Unresolved
InfoLack of Events for Critical Actions
Several critical state-changing functions, such as mintInflation(), burn(), lockPool(), unlockPool(), and updateMintRate(), do not emit corresponding events. Emitting events is crucial for off-chain monitoring, indexing, and providing transparency into the contract's operations. Without events, it is difficult for users, block explorers, and external systems to track these significant actions.I-01
Issue
Several critical state-changing functions, such as mintInflation(), burn(), lockPool(), unlockPool(), and updateMintRate(), do not emit corresponding events. Emitting events is crucial for off-chain monitoring, indexing, and providing transparency into the contract's operations. Without events, it is difficult for users, block explorers, and external systems to track these significant actions.
Fix
Emit events for all critical state-changing actions. For example, MintInflation(address indexed minter, uint256 amount), TokensBurned(address indexed burner, uint256 amount), PoolLocked(address indexed poolAddress), PoolUnlocked(address indexed poolAddress), and MintRateUpdated(uint256 oldRate, uint256 newRate).
Status
Unresolved
Analysis
AI Copilotas of audit · Sep 4The DERC20 contract demonstrates good architectural practices by inheriting from battle-tested OpenZeppelin contracts (ERC20, ERC20Votes, ERC20Permit, Ownable) and utilizing custom error messages for clarity (7.1 Architecture, 7.2 Code Security). The inflation mechanism, while complex, appears to correctly implement compounded yearly minting. However, a critical flaw exists where vested tokens are minted to the contract but no public function is provided for recipients to claim them (7.1 Architecture, 7.8 Operations). Furthermore, the isPoolUnlocked state variable and associated lockPool/unlockPool functions do not enforce any transfer restrictions, rendering the pool locking mechanism non-functional (7.1 Architecture, 7.2 Code Security).
The contract exhibits a high degree of centralized control, as the owner role, inherited from Ownable, possesses significant power (7.3 Access Control, 7.5 Governance). The owner can mint inflation tokens, burn tokens from their own address, and update the yearlyMintRate, which directly impacts the token's supply and economics (7.4 Economic). While the updateMintRate function includes a safeguard to mint pending inflation before changing the rate, the sole control over these parameters by a single address introduces a substantial governance and economic risk.
The provided contract is not implemented as an upgradeable proxy. Therefore, upgradeability risks are not applicable to this specific deployment. Any changes to the contract logic would require a new deployment and migration of assets.
It is critical to implement a public function allowing vested token recipients to claim their allocated amounts.
Without this, the vesting mechanism is entirely non-functional. Additionally, the pool locking mechanism should either be removed or fully implemented to enforce transfer restrictions as intended. Consider implementing a multi-signature wallet for the owner role to mitigate the risks associated with centralized control over critical functions like inflation minting and rate updates.
Contract & Record
Free for any token on the record. It links to this page and always shows the current score and the date it was checked.
- Sep 4, 202647Medium
- Jul 29, 202646Medium
Score changes are recorded as dated snapshots — history is append-only and cannot be edited.
Frequently Asked Questions
What is the GITLAWB contract address?
The gitlawb contract on Base is 0x5f980dcfc4c0fa3911554cf5ab288ed0eb13dba3. Compare it with the address the project itself publishes before trading: other contracts can carry the same name and ticker.
Is gitlawb a scam?
Quantum Audit's risk score for gitlawb is 47/100 (Medium risk) as of Sep 4, 2026, computed by a deterministic function from on-chain facts — Contract verified: Verified; Ownership: Retained; Mint: No mint; Liquidity lock: Not locked; Upgradeability: Fixed code. A score is a dated snapshot of those facts, not a guarantee; each one is listed on this page.
Is GITLAWB liquidity locked?
Liquidity lock: Not locked (as of Sep 4, 2026). Total DEX liquidity: $603.4K.
Who holds GITLAWB?
As of Sep 4, 2026, the 10 largest holders own 37.2% of the supply. The Holders section on this page shows who they are by holder type.
Would You Like a More Detailed Audit of gitlawb?
Our AI-powered scanner gives you a deeper, real-time smart contract analysis — free, with every scoring factor shown.
Get Detailed Audit Is this your token? Publish your own audit on this page