You can model this more loosely coupled by creating two Aggregates and utilize Domain Events.
Project RemainingBudget OnContractAdded(costsContract) RemainingBudget.Subtract(Contract.costs) RaiseDomainEvent(ProjectBudgetReducedEvent(ProjectId, RemainingBudget)) and
Objective ProjectId RemainingProjectBudget List<Contracts> OnProjectBudgetReduced(ProjectId, RemainingBudget) if(ProjectId != this.ProjectId) return RemainingProjectBudget = RemainingBudget AddContract(Contract) if(Contract.Cost > RemainingProjectBudget) return Error Contracts.Add(Contract) RaiseDomainEvent(ContractAdded(Contract.cost)) In the application layer, you will have to add some event handlers and a mechanism to dispatch events when saving changes to an aggregate. That adds a bit of complexity in that layer, but in return you will get a cleaner domain layer without the deep hierarchy.