Skip to content

feat: pwn subgraph #41

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 14 commits into
base: master
Choose a base branch
from
Open

feat: pwn subgraph #41

wants to merge 14 commits into from

Conversation

microHoffman
Copy link
Collaborator

@microHoffman microHoffman commented Jun 13, 2025

Description by Korbit AI

What change is being made?

Add a PWN subgraph package with configuration, setup instructions, and ABI contract files.

Why are these changes being made?

These changes provide the necessary implementation to support the PWN subgraph, enabling interaction with smart contracts through the generated subgraph. The inclusion of ABIs and Docker setup facilitates building and running the subgraph efficiently within a development environment.

Is this description stale? Ask me to generate a new description by commenting /korbit-generate-pr-description

@microHoffman microHoffman self-assigned this Jun 13, 2025
Copy link

korbit-ai bot commented Jun 13, 2025

Korbit doesn't automatically review large (3000+ lines changed) pull requests such as this one. If you want me to review anyway, use /korbit-review.

@microHoffman
Copy link
Collaborator Author

/korbit-review

Copy link

@korbit-ai korbit-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review by Korbit AI

Korbit automatically attempts to detect when you fix issues in new commits.
Category Issue Status
Performance Inefficient Byte Conversion Chain ▹ view
Error Handling Missing Error Handling ▹ view
Readability Unclear underscore prefix in variable name ▹ view
Readability Complex One-liner for Byte Conversion ▹ view
Performance Missing Account Cache for Repeated Lookups ▹ view
Design Redundant Pass-Through Function ▹ view
Design Missing Critical Logging Implementation ▹ view
Performance Inefficient Entity Creation Pattern ▹ view
Design Remove Dead Code ▹ view
Functionality Unsafe Feed ID Generation ▹ view
Files scanned
File Path Reviewed
packages/subgraph/src/hub.ts
packages/subgraph/src/helpers.ts
packages/subgraph/src/multi-token-category-registry.ts
packages/subgraph/src/chainlink-feed-registry.ts
packages/v1-core/src/contracts/elastic-proposal-contract.ts
packages/v1-core/src/contracts/chain-link-proposal-contract.ts
packages/subgraph/src/loan-token.ts
packages/subgraph/src/simple-loan-simple-proposal.ts
packages/subgraph/src/simple-loan-elastic-proposal.ts
packages/subgraph/src/simple-loan-list-proposal.ts
packages/subgraph/src/simple-loan-uniswap-v-3-lp-set-proposal.ts
packages/subgraph/src/simple-loan-uniswap-v-3-lp-individual-proposal.ts
packages/subgraph/src/config.ts
packages/subgraph/src/simple-loan-elastic-chainlink-proposal.ts
packages/subgraph/src/utils.ts
packages/subgraph/src/simple-loan.ts

Explore our documentation to understand the languages and file types we support and the files we ignore.

Check out our docs on how you can make Korbit work best for you and your team.

Loving Korbit!? Share us on LinkedIn Reddit and X

entity.blockTimestamp = event.block.timestamp
entity.transactionHash = event.transaction.hash

entity.save()
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing Error Handling category Error Handling

Tell me more
What is the issue?

No error handling is implemented for the entity save operation, which could fail silently.

Why this matters

If the save operation fails, the event data would be lost without any indication of the failure, potentially leading to incomplete or inconsistent data in the subgraph.

Suggested change ∙ Feature Preview

Implement try-catch block for error handling:

try {
  entity.save()
} catch (error) {
  log.error('Error saving TagSetEvent entity: {}', [error.toString()])
  throw error
}
Provide feedback to improve future suggestions

Nice Catch Incorrect Not in Scope Not in coding standard Other

💬 Looking for more details? Reply to this comment to chat with Korbit.

const entity = new TagSetEventEntity(
event.transaction.hash.concatI32(event.logIndex.toI32()),
)
entity._address = event.params._address
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unclear underscore prefix in variable name category Readability

Tell me more
What is the issue?

Variable name starts with underscore without clear indication of why the prefix is used.

Why this matters

In TypeScript, leading underscores typically indicate private members or unused variables. Using it here without clear intent can confuse readers about the variable's purpose or scope.

Suggested change ∙ Feature Preview
entity.address = event.params.address // Remove underscore if not needed for privacy/unused variable indication
Provide feedback to improve future suggestions

Nice Catch Incorrect Not in Scope Not in coding standard Other

💬 Looking for more details? Reply to this comment to chat with Korbit.

Comment on lines +18 to +20
export function getAssetId(assetAddress: Address, assetId: BigInt): Bytes {
return assetAddress.concat(Bytes.fromByteArray(Bytes.fromBigInt(assetId)));
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Complex One-liner for Byte Conversion category Readability

Tell me more
What is the issue?

The nested function calls in a single line make the byte conversion and concatenation operations hard to follow.

Why this matters

Complex one-liners reduce code readability and make debugging more difficult. Breaking down the operations into steps with intermediate variables makes the code's intent clearer.

Suggested change ∙ Feature Preview
export function getAssetId(assetAddress: Address, assetId: BigInt): Bytes {
	const assetIdBytes = Bytes.fromBigInt(assetId);
	const assetIdByteArray = Bytes.fromByteArray(assetIdBytes);
	return assetAddress.concat(assetIdByteArray);
}
Provide feedback to improve future suggestions

Nice Catch Incorrect Not in Scope Not in coding standard Other

💬 Looking for more details? Reply to this comment to chat with Korbit.

Comment on lines +5 to +12
export function getOrCreateAccount(address: Address): Account {
let account = Account.load(address);
if (account == null) {
account = new Account(address);
account.save();
}
return account;
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing Account Cache for Repeated Lookups category Performance

Tell me more
What is the issue?

Each 'getOrCreateAccount' call performs a database load operation and potentially a save operation without any caching mechanism.

Why this matters

In high-frequency scenarios where the same account is accessed multiple times, repeated database operations can create unnecessary I/O overhead and impact performance.

Suggested change ∙ Feature Preview

Implement an in-memory cache for recently accessed accounts using a Map data structure. Example:

let accountCache = new Map<string, Account>();

export function getOrCreateAccount(address: Address): Account {
    let id = address.toHexString();
    let cached = accountCache.get(id);
    if (cached) return cached;

    let account = Account.load(address);
    if (account == null) {
        account = new Account(address);
        account.save();
    }
    accountCache.set(id, account);
    return account;
}
Provide feedback to improve future suggestions

Nice Catch Incorrect Not in Scope Not in coding standard Other

💬 Looking for more details? Reply to this comment to chat with Korbit.

}

export function getAssetId(assetAddress: Address, assetId: BigInt): Bytes {
return assetAddress.concat(Bytes.fromByteArray(Bytes.fromBigInt(assetId)));
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Inefficient Byte Conversion Chain category Performance

Tell me more
What is the issue?

Multiple unnecessary byte conversions in getAssetId function creating temporary byte arrays.

Why this matters

Each conversion (BigInt to Bytes to ByteArray back to Bytes) creates temporary objects and performs redundant operations, impacting performance with unnecessary memory allocations.

Suggested change ∙ Feature Preview

Simplify the byte conversion process by using a direct conversion method:

export function getAssetId(assetAddress: Address, assetId: BigInt): Bytes {
    return assetAddress.concat(Bytes.fromBigInt(assetId));
}
Provide feedback to improve future suggestions

Nice Catch Incorrect Not in Scope Not in coding standard Other

💬 Looking for more details? Reply to this comment to chat with Korbit.

Comment on lines +14 to +16
export function getAssetContractId(assetAddress: Address): Bytes {
return assetAddress;
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Redundant Pass-Through Function category Design

Tell me more
What is the issue?

The getAssetContractId function serves as a simple pass-through without any transformation or business logic, making it an unnecessary abstraction.

Why this matters

Unnecessary abstractions increase code complexity and maintenance overhead without providing any benefits. In this case, callers could directly use the assetAddress.

Suggested change ∙ Feature Preview

Either remove the function and use assetAddress directly at call sites, or add meaningful transformation logic if required:

// If additional logic is needed:
export function getAssetContractId(assetAddress: Address): Bytes {
    // Add necessary transformation or validation
    return assetAddress;
}

// Otherwise, remove the function entirely
Provide feedback to improve future suggestions

Nice Catch Incorrect Not in Scope Not in coding standard Other

💬 Looking for more details? Reply to this comment to chat with Korbit.

Comment on lines +4 to +12
// TODO add logs where applicable
export function getOrCreateAccount(address: Address): Account {
let account = Account.load(address);
if (account == null) {
account = new Account(address);
account.save();
}
return account;
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing Critical Logging Implementation category Design

Tell me more
What is the issue?

The TODO comment indicates missing logging functionality, which is important for monitoring and debugging in a production environment.

Why this matters

Without proper logging, it becomes difficult to track account creation and loading operations, hampering debugging and monitoring capabilities.

Suggested change ∙ Feature Preview

Implement appropriate logging:

export function getOrCreateAccount(address: Address): Account {
	let account = Account.load(address);
	if (account == null) {
		log.info('Creating new account for address {}', [address.toHexString()]);
		account = new Account(address);
		account.save();
	}
	return account;
}
Provide feedback to improve future suggestions

Nice Catch Incorrect Not in Scope Not in coding standard Other

💬 Looking for more details? Reply to this comment to chat with Korbit.

Comment on lines +15 to +18
let chainlinkFeed = ChainlinkFeed.load(chainlinkFeedId)
if (chainlinkFeed == null) {
chainlinkFeed = new ChainlinkFeed(chainlinkFeedId)
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Inefficient Entity Creation Pattern category Performance

Tell me more
What is the issue?

Redundant entity load operation when creating new entities in high-frequency event handlers.

Why this matters

Loading entities from storage is an expensive operation. For high-frequency events, this check-then-create pattern adds unnecessary overhead when most calls will create new entities.

Suggested change ∙ Feature Preview

If the business logic allows, consider using a more performant pattern that assumes new creation:

let chainlinkFeed = new ChainlinkFeed(chainlinkFeedId)
Provide feedback to improve future suggestions

Nice Catch Incorrect Not in Scope Not in coding standard Other

💬 Looking for more details? Reply to this comment to chat with Korbit.

Comment on lines +25 to +57
// const entity = new FeedConfirmed(
// event.transaction.hash.concatI32(event.logIndex.toI32()),
// )
// entity.asset = event.params.asset
// entity.denomination = event.params.denomination
// entity.latestAggregator = event.params.latestAggregator
// entity.previousAggregator = event.params.previousAggregator
// entity.nextPhaseId = event.params.nextPhaseId
// entity.sender = event.params.sender

// entity.blockNumber = event.block.number
// entity.blockTimestamp = event.block.timestamp
// entity.transactionHash = event.transaction.hash

// entity.save()
}

// export function handleFeedProposed(event: FeedProposedEvent): void {
// const entity = new FeedProposed(
// event.transaction.hash.concatI32(event.logIndex.toI32()),
// )
// entity.asset = event.params.asset
// entity.denomination = event.params.denomination
// entity.proposedAggregator = event.params.proposedAggregator
// entity.currentAggregator = event.params.currentAggregator
// entity.sender = event.params.sender

// entity.blockNumber = event.block.number
// entity.blockTimestamp = event.block.timestamp
// entity.transactionHash = event.transaction.hash

// entity.save()
// }
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove Dead Code category Design

Tell me more
What is the issue?

Large blocks of commented-out code are left in the codebase, creating unnecessary cognitive load and maintenance burden.

Why this matters

Commented code creates confusion about whether it might be needed in the future, makes the codebase harder to maintain, and clutters the source file. Version control systems should be used to track code history instead.

Suggested change ∙ Feature Preview

Either remove the commented code entirely or, if it represents important logic that might be needed later, document it properly in documentation or tickets rather than leaving it as comments in the source code.

Provide feedback to improve future suggestions

Nice Catch Incorrect Not in Scope Not in coding standard Other

💬 Looking for more details? Reply to this comment to chat with Korbit.

Comment on lines +9 to +11
function getChainlinkFeedId(event: FeedConfirmedEvent): Bytes {
return event.params.asset.concat(event.params.denomination)
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unsafe Feed ID Generation category Functionality

Tell me more
What is the issue?

The chainlink feed ID construction using simple concatenation of asset and denomination could lead to ID collisions.

Why this matters

If two different pairs of assets and denominations happen to have the same concatenated value (e.g., 'ETHUSDT' could be either ETH/USDT or ET/HUSDT), it would cause incorrect data overwrites in the database.

Suggested change ∙ Feature Preview

Add a separator between asset and denomination to ensure unique IDs:

function getChainlinkFeedId(event: FeedConfirmedEvent): Bytes {
  return event.params.asset.concat(Bytes.fromUTF8('-')).concat(event.params.denomination)
}
Provide feedback to improve future suggestions

Nice Catch Incorrect Not in Scope Not in coding standard Other

💬 Looking for more details? Reply to this comment to chat with Korbit.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants